C++ - В чем разница между встроенными строками, определенными в CPP и H

Это не столько вопрос "У меня возникла эта проблема", сколько вопрос "Я действительно хочу понять, как лучше работает язык".

Недавно я начал сталкиваться с определениями встроенных функций в файлах .cpp для данного класса. Я хотел бы понять, в чем на самом деле разница между точками определения встроенной функциональности. При проведении анализа встроенных строк, определенных в CPP, на уровне объекта кажется, что гораздо более высокий процент встроенных строк, объявленных в C++ (в отличие от определенных в .h), оптимизированы для сопоставленных функций, а не законно встроены - это это главное отличие, или за этим стоит какая-то другая цель, которую я не вижу.


person Kat    schedule 27.08.2012    source источник
comment
Не могли бы вы представить несколько примеров кода? На самом деле непонятно, что вы говорите.   -  person Richard J. Ross III    schedule 27.08.2012
comment
В частности, я искал разницу между встроенным Class::foo(void){stuff}, помещаемым в .h для данного класса, и в .cpp для данного класса.   -  person Kat    schedule 29.08.2012


Ответы (5)


Нет никакой разницы. inline — это подсказка для компилятора, но в наши дни она не особенно важна, поскольку компиляторы довольно хорошо выясняют, следует ли расширять встроенные функции без вашей помощи (см. ключевое слово register).

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

Когда встроенная функция определена в файле .cpp, ее определение видно только в этом файле, поэтому вызов ее из какого-либо другого исходного файла не будет работать.

person Pete Becker    schedule 27.08.2012

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

person slavemaster    schedule 27.08.2012
comment
Это не совсем так. Это зависит от вашего компилятора. Например, если вы используете Visual C++, вы можете включить оптимизацию всей программы. В этом случае компоновщик может встраивать функции независимо от того, определены ли они в одной и той же единице перевода. - person Peter Ruderman; 27.08.2012
comment
В соответствии со стандартом C++03, §7.1.2.4 Встроенная функция должна быть определена в каждой единице перевода, в которой она используется, и должна иметь точно такое же определение в каждом случае (§3.2). Меня не особо интересуют расширения конкретных компиляторов :-p - person slavemaster; 27.08.2012
comment
Могу я смиренно предложить вам быть? Оптимизация всей программы — это замечательная функция. - person Peter Ruderman; 27.08.2012
comment
@PeterRuderman, ха-ха, тогда очень хорошо... Я даже не программист на C++, но в следующий раз, когда мне придется писать код на C++, я попробую :-) - person slavemaster; 27.08.2012
comment
@PeterRuderman, я думаю, что он прав - даже если вы используете оптимизацию всей программы, она будет встроена в функцию независимо от того, использовали ли вы ключевое слово inline. - person Mark Ransom; 27.08.2012
comment
Извините, я, кажется, создаю некоторую путаницу между ключевым словом inline и глаголом to inline. Вы правы: компилятору не нужно ключевое слово inline, чтобы встроить функцию. (И на самом деле, я думаю, что большинство современных компиляторов полностью игнорируют ключевое слово inline и сами решают, что встраивать.) - person Peter Ruderman; 27.08.2012

Вполне вероятно, что разница является результатом того, что ваш компилятор не выполняет оптимизацию "время компоновки"/"всей программы". Это когда компилятор выполняет оптимизацию, просматривая всю программу, а не только одну единицу перевода. Он часто не включен по умолчанию даже в компиляторах, которые его поддерживают, потому что он обычно требует очень большого использования памяти.

При оптимизации только на уровне единицы перевода невозможно встроить функции, определенные в других исходных файлах, поскольку определение недоступно.

person Dirk Holsopple    schedule 27.08.2012

Компилятору легче встроить встроенную функцию, если она определена до вызова, а не после. Поскольку файлы заголовков обычно включаются в начало исходного кода, это условие легче выполнить.

person Mark Ransom    schedule 27.08.2012

Технически разницы нет нет.

Хотя я мало что знаю об их оптимизации, подумайте об этом...

Препроцессор сначала расширит файл .h, где он найдет #include в файле .cpp. И затем он будет представлен компилятору. Так что технически никакой разницы нет.

Но есть правило:

Функция inline должна быть определена в каждой единице компиляции, в которой она вызывается. (Конечно, необходимо соблюдать ODR).

Это связано с тем, что каждая единица компиляции обрабатывается отдельным экземпляром программы-компилятора.

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

person Sam    schedule 08.11.2013