Встроенный прототип функции против регулярной декларации против прототипа

В чем разница между встроенной функцией, а затем главной:

inline double cube(double side)
{
   return side * side * side;
}

int main( )
{
    cube(5);
}

против просто объявления функции, как:

double cube(double side)
{
   return side * side * side;
}

int main( )
{
    cube(5);
}

vs прототип функции?

double cube(double);

int main( )
{
    cube(5);
}

double cube(double side)
{
   return side * side * side;
}
3
возможный дубликат встроенной функции c ++? - также cf. этот ответ моих .
добавлено автор Kerrek SB, источник
Вы имели в виду cube (5); ?
добавлено автор log0, источник
Я предположил, что да.
добавлено автор log0, источник

4 ответы

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

//cube.h
inline double cube(double side)
{
   return side * side * side;
}

//cube.cpp
int main( )
{
    cube(5);
}

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

//cube.cpp
double cube(double side)
{
   return side * side * side;
}

int main( )
{
    cube(5);
}

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

//cube.h
double cube(double);

//cube.cpp
int main( )
{
    cube(5);
}

double cube(double side)
{
   return side * side * side;
}
6
добавлено
Отличное и понятное объяснение, сэр/мэм. Большое спасибо!
добавлено автор iggy2012, источник
Последний пример - неопределенное поведение без необходимости диагностики, если cube.h включен как cube.cpp , так и другой единицей перевода. Функция не может быть inline в одном модуле, а не внутри - в другом.
добавлено автор M.M, источник
Во втором примере было бы хорошей практикой отметить функцию как внутреннюю связь, чтобы избежать случайного неопределенного поведения, если какая-то другая часть проекта также выполняет функцию, называемую cube
добавлено автор M.M, источник
... может быть определен в одном модуле компиляции (cpp file + includes) несколько раз - вы имели в виду разные единицы компиляции?
добавлено автор anatolyg, источник
@MooingDuck: anatolyg прав, функция inline может быть определена только один раз в блоке трансляции, даже если она может быть определена несколько раз в программе, не нарушая ODR.
добавлено автор David Rodríguez - dribeas, источник
Нет, inline разрешено нарушать ODR, например, шаблоны. В противном случае было бы сложно разместить встроенный заголовок, и если бы он не был в заголовке, глупые компиляторы не смогли бы его встроить!
добавлено автор Mooing Duck, источник
О, верно, я ошибся. Забыл о включенных охранниках.
добавлено автор Mooing Duck, источник
@ M.M: Исправлен дополнительный inline в последнем примере, спасибо. Вы правильно относитесь к внутренней привязке, но это лишняя сложность, которая не очень подходит для ответа.
добавлено автор Mooing Duck, источник
Почему это не принято в качестве ответа.
добавлено автор Felype, источник

Производительность мудрая, они все одинаковы, поскольку inline - это всего лишь подсказка для компилятора. Если используется разделение декларации/определения, а определение - на другой единицы перевода, тогда компилятор будет сложнее встроить его (но есть реализации, которые делают это).

Разница с созданием функции inline или нет - это то, что компоновщик не будет жаловаться, если он видит одно и то же встроенное определение функции более одного раза.

1
добавлено

Программа 3 скомпилируется точно так же с g ++ -S -O3 $ file.cc . За исключением второго примера, в котором определение double cube (double side) по-прежнему существует в нестрочной форме, хотя указано в int main() .

_main:
pushl   %ebp
movl    $16, %eax
movl    %esp, %ebp
subl    $8, %esp
andl    $-16, %esp
call    __alloca
call    ___main
leave
xorl    %eax, %eax
ret
1
добавлено
Разница, которую вы указываете, является деталью реализации, некоторые компиляторы будут генерировать все функции всегда, даже если они фактически встроены, потому что вам разрешено получать адрес функции inline , а компилятор может не работать знать при обработке функции, если позже в том же ТУ будет запрошен адрес функции.
добавлено автор David Rodríguez - dribeas, источник
@David Точно.
добавлено автор log0, источник

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

Я не уверен, что произойдет в третьем примере. Я предполагаю, что это будет зависеть от используемой цепочки инструментов.

0
добавлено
Последний - всего лишь прототип функции перед main (). Кажется, все они работают одинаково, но я не понимаю, в чем разница.
добавлено автор iggy2012, источник
pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest