Код в заголовочных файлах будет всегда встраиваться?

У меня просто было обсуждение с коллегой относительно кода в заголовочных файлах:

Он говорит, что код, определенный в заголовочных файлах, будет всегда встраиваться компилятором (как код от функционального GetNumber () в моем заголовке в качестве примера). Я говорю, что это будет иногда встраиваться, каждый раз, когда компилятор решает сделать так. Таким образом, какой из нас должен принести пирог для работы на то, что сказал грязной неправде? Или возможно мы оба неправы...?

MyClass.hpp

   class MyClass
    {
    public:
    MyClass();
    ~MyClass();

    int GetNumber() const 
    {
     //...; 
     return m_number;
    };

    private:
    int m_number;
    };
14
задан nabulke 27 July 2010 в 10:49
поделиться

7 ответов

Любая функция, определенная в классе (например, ваш пример GetNumber), а не только что объявленная, неявно встроена в . Это означает, что это эквивалентно использованию ключевого слова inline , поэтому многократное включение заголовка не вызовет ошибок ссылки из-за нескольких определений этих функций.

Большинство современных компиляторов рассматривают inline как команду связывания и не более того. Некоторые компиляторы предоставляют более сильные ключевые слова, такие как CL __ forceinline , которые означают «встроить это, если это возможно».

Итак, вы оба в какой-то степени правы и оба ошибаетесь.

12
ответ дан 1 December 2019 в 09:00
поделиться

На самом деле оба верны. То, как вы, ребята, имели в виду, немного другое. ( Я думаю)

Из стандартного документа C ++ для встроенной функции,

  1. Объявление функции (8.3.5, 9.3, 11.4) со встроенным спецификатором объявляет встроенную функцию.

2. Функция, определенная в классе определение - это встроенная функция.

Итак, как сказал ваш коллега, это действительно встроенная функция .

Но подстановка кода для встроенной функции вместо обычного вызова функции зависит от компилятора . ( Я надеюсь, это именно то, что ВЫ имеете в виду ) Даже если компилятор не заменяет, это все равно встроенная функция.

Надеюсь, это снимет вашу озабоченность ..

4
ответ дан 1 December 2019 в 09:00
поделиться

Твой приятель неправ, ты прав.

Встраивание не зависит от того, где находится код (заголовок или нет). После предварительной обработки нет заголовков и не заголовков. Весь блок - это один файл, содержащий все включенные в него данные.

Попробуйте запустить препроцессор gcc, и вы увидите:

gcc -E some_source_file_with_includes
7
ответ дан 1 December 2019 в 09:00
поделиться

Функция-член класса, определенная (в отличие от только , объявленных ) в определении класса, является неявно встроенной . Другого кода в заголовках нет.

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

void print(std::ostream& os)
{
  os << "Hello, world!\n";
}

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

Однако есть еще несколько нарушений. Например, определение константы автоматически получит внешнюю связь. Следовательно,

const int answer = 42;

в заголовке не заставит компоновщик жаловаться на множественные определения ответа , в то время как

int question;

будет.

2
ответ дан 1 December 2019 в 09:00
поделиться

Это не так, только код в функциях-членах будет инкрустирован (если компилятор решит это сделать), если он указан в объявлении класса. Однако он должен разрешить определение членов, поэтому они могут быть объявлены как эквивалент static языка C (что позволит использовать их в пределах единицы компиляции, но не может быть связано с другими объектными файлами), что поместит одну версию в каждый объектный файл. Попробуйте сами, и вы заметите, что если вы не укажете ключевое слово inline для чего-либо вне объявления класса, вы получите дубликаты.

1
ответ дан 1 December 2019 в 09:00
поделиться

Компилятор решает. Даже использование _inline только говорит компилятору, что вы предпочитаете инлайн-код, но анализатор затрат/выгод компилятора может решить иначе.

Вы можете использовать _forceinline, если вы используете Microsoft C++, чтобы сделать код инлайн, но это может привести к увеличению размера двоичных файлов.

1
ответ дан 1 December 2019 в 09:00
поделиться

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

3
ответ дан 1 December 2019 в 09:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: