встроенный экстерн

86
задан Deduplicator 18 February 2015 в 15:12
поделиться

4 ответа

Я полагаю, что Вы неправильно понимаете __ ФАЙЛ __ и __ СТРОКА __ на основе этого оператора:

, потому что это использует __ ФАЙЛ __ и __ СТРОКА __ макросы, которые должны решить для вызывающей стороны, но не этой вызванной функции

, существует несколько фаз компиляции, и предварительная обработка является первой. __ ФАЙЛ __ и __ СТРОКА __ заменяются во время той фазы. Таким образом к тому времени, когда компилятор может рассмотреть функцию для встраивания, они были уже заменены.

29
ответ дан 24 November 2019 в 08:01
поделиться

Это кажется, что Вы пытаетесь записать что-то вроде этого:

inline void printLocation()
{
  cout <<"You're at " __FILE__ ", line number" __LINE__;
}

{
...
  printLocation();
...
  printLocation();
...
  printLocation();

и надеющийся то, что Вы получите различные значения, распечатало каждый раз. Как Don говорит, Вы не будете, потому что __ ФАЙЛ __ и __ СТРОКА __ реализована препроцессором, но встроенный реализован компилятором. Таким образом везде, где Вы называете printLocation от, Вы получите тот же результат.

только способ, которым можно заставить это работать, состоит в том, чтобы сделать printLocation макросом. (Да, я знаю...)

#define PRINT_LOCATION  {cout <<"You're at " __FILE__ ", line number" __LINE__}

...
  PRINT_LOCATION;
...
  PRINT_LOCATION;
...
13
ответ дан 24 November 2019 в 08:01
поделиться

Ситуация со встроенным, встроенным статическим и встроенный экстерн является сложной, не в последнюю очередь потому что gcc и C99 определяют немного отличающиеся значения для их поведения (и по-видимому C++, также). Можно найти некоторую полезную и подробную информацию о том, что они делают в C здесь .

3
ответ дан 24 November 2019 в 08:01
поделиться

в K& R C или C89, встроенный, не была часть языка. Много компиляторов реализовали его как расширение, но не было никакой определенной семантики относительно того, как это работало. GCC был среди первого для реализации встраивания и представил inline, static inline, и extern inline конструкции; большая часть pre-C99 компилятора обычно следует своему примеру.

GNU89:

  • inline: функция может быть встроена (это - просто подсказка хотя). Исключительная версия всегда испускается и внешне видимая. Следовательно можно было только определить такое встроенное в одной единице компиляции, и любой должен рассматривать его как исключительную функцию (или Вы получите дублирующиеся символы во время ссылки).
  • extern inline не генерирует исключительную версию, но мог бы назвать одну (который поэтому необходимо определить в некоторой другой единице компиляции. Правило с одним определением применяется, хотя; исключительная версия должна иметь тот же код как встроенное, предлагаемое здесь, в случае, если вызовы компилятора это вместо этого.
  • static inline не генерирует внешне видимую исключительную версию, хотя она могла бы генерировать файл статический. Правило с одним определением не применяется, так как никогда нет испускаемого внешнего символа, ни вызова одному.

C99 (или GNU99):

  • inline: как GNU89 "встроенный экстерн"; никакая внешне видимая функция не испускается, но можно было бы быть назван и так должен существовать
  • extern inline: как "встроенный" GNU89: внешне видимый код испускается, таким образом, самое большее одна единица перевода может использовать это.
  • static inline: как GNU89, "статичный встроенный". Это - единственное портативное между gnu89 и C++ c99

:

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

125
ответ дан 24 November 2019 в 08:01
поделиться