Встроенное ключевое слово против определения заголовка

В чем разница между использованием встроенного ключевого слова перед функцией и простым объявлением всей функции в заголовке?

так...

<code>int whatever() { return 4; }
</code>

против

.час:

<code>inline int whatever();
</code>

.cpp:

<code>inline int myClass::whatever()
{
    return 4;
}
</code>

в этом отношении, что это делает:

<code>inline int whatever() { return 4; }
</code>

Ответы на вопрос(5)

without inline, вы, скорее всего, в конечном итоге с несколькими экспортированными символами,if the function is declared at the namespace or global scope (приводит к ошибкам компоновщика).

однако для класса (как видно из вашего примера) большинство компиляторов неявно объявляют метод как встроенный (-fno-default-inline отключит это значение по умолчанию в GCC).

если вы объявите функцию как встроенную, компилятор может ожидать увидеть ее определение в переводе. следовательно, вы должны зарезервировать его на время, когда определение является видимым.

на более высоком уровне: определение в объявлении класса часто видимо для большего количества переводов. это может привести к лучшей оптимизации, и это может привести к увеличению времени компиляции.

если оптимизация рук и быстрые компиляции не являются важными, в наши дни необычно использовать ключевое слово в объявлении класса.

Есть несколько аспектов:

Language

When a function is marked with the inline keyword, then its definition should be available in the TU or the program is ill-formed. Any function defined right in the class definition is implicitly marked inline. A function marked inline (implicitly or explicitly) may be defined in several TUs (respecting the ODR), whereas it is not the case for regular functions. Template functions (not fully specialized) get the same treatment as inline ones.

Compiler behavior

A function marked inline will be emitted as a weak symbol in each object file where it is necessary, this may increase their size (look up template bloat). Whereas the compiler actually inlines the call (ie, copy/paste the code at the point of use instead of performing a regular function call) is entirely at the compiler's discretion. The presence of the keyword may, or not, influence the decision but it is, at best, a hint.

Linker behavior

Weak symbols are merged together to have a single occurrence in the final library. A good linker could check that the multiple definitions concur but this is not required.
 31 янв. 2014 г., 17:35
@DavidKernin: если шаблонная функция полностью специализирована, то она больше не является "универсальной" и напоминают «обычный» функция, и, следовательно, компилятору не нужно выдавать слабый символ, если вы не пометите егоinline.
 04 дек. 2012 г., 19:58
На уровне персонажа или на уровне токена?
 26 сент. 2012 г., 09:36
Что вы подразумеваете под "TU"? и "ODR"?
 05 дек. 2012 г., 08:27
@FredOverflow:Tokens в формальном определении. Если вы посмотрите & # xA7; 3.2 / 6, вы также обратите внимание на требования к поиску имени и другим уточнениям в отношении шаблонов. ODR - сложный зверь: x
 26 сент. 2012 г., 11:07
@WiSaGaN: TU = Единица перевода: грубо говоря, предварительно обработанный исходный файл. ODR = одно правило определения: требуется, чтобы все определения функции / класса были одинаковыми на уровне символов для разных TU.

Цельinline состоит в том, чтобы позволить функции быть определенной в более чем одном блоке перевода, что необходимо для некоторых компиляторов, чтобы иметь возможность встроить ее везде, где она используется. Его следует использовать всякий раз, когда вы определяете функцию в заголовочном файле, хотя вы можете опустить ее при определении шаблона или функцию внутри определения класса.

Определение его в заголовке безinline очень плохая идея; если вы включаете заголовок из нескольких единиц перевода, то вы нарушаете правило единого определения; ваш код, вероятно, не будет ссылаться и может показывать неопределенное поведение, если это так.

Объявив это в шапке сinline но определение его в исходном файле также очень плохая идея; определение должно быть доступно в любой единице перевода, которая его использует, но, определяя ее в исходном файле, оно доступно только в одной единице перевода. Если другой исходный файл содержит заголовок и пытается вызвать функцию, то ваша программа недействительна.

Если вы связываете несколько объектов в исполняемый файл, обычно должен быть только один объект, содержащий определение функции. Заint whatever() { return 4; } - любая единица перевода, которая используется для создания объекта, будет содержать определение (то есть исполняемый код) дляwhatever функция. Линкер не будет знать, на кого направлять абонентов. Еслиinline предоставляется, тогда исполняемый код может быть встроен или не встроен в узлы вызова, но если он не является компоновщиком, ему разрешается предполагать, что все определения одинаковы, и произвольно выбирать одно для направления вызывающим абонентам. Если каким-либо образом определения не совпадают, то это считается ВАШЕЙ ошибкой, и вы получаете неопределенное поведение. Использоватьinlineопределение должно быть известно при компиляции вызова, поэтому ваша идея поместить встроенное объявление в заголовок и встроенное определение в файл .cpp будет работать только в том случае, если все вызывающие объекты окажутся позже в том же файле .cpp - в В общем, оно повреждено, и вы ожидаете, что определение (номинально) встроенной функции появится в заголовке, который ее объявляет (или для того, чтобы было одно определение без предварительного объявления).

Этот вопрос многое объясняет о встроенных функцияхЧто означает __inline__? (хотя это было оinline ключевое слово.)

По сути, это не имеет ничего общего с заголовком. Объявление всей функции в заголовке просто меняет исходный файл, в котором находится источник функции. Ключевое слово Inline изменяет, гдеresulting compiled function будет помещен на его собственное место, так что каждый звонок будет идти туда или вместо каждого звонка (лучше для производительности). Однако компиляторы иногда выбирают, какие функции или методы сделать встроенными для себя, а ключевые слова простоsuggestions для компилятора. Даже функции, которые не были заданы встроенными, могут быть выбраны компилятором, чтобы они стали встроенными, если это дает лучшую производительность.

Ваш ответ на вопрос