История изменений
Исправление
Moisha_Liberman,
(текущая версия)
:
А что даёт «extern inline»?
И почему не линкуется, если после препроцессинга все недостающие функции всё равно оказываются в файле?
Идея inline ф-ий заключается в их подстановке при компиляции и линковке. При отсутствии оптимизаций gcc гонит всё «как есть» линкеру, не выстраивая оптимизированную таблицу перекрёстных ссылок. При отсутствии оптимизаций (-О0 же!) ни каких оптимизаций не производится и инлайнинга тоже. Ф-я не подставляется без оптимизаций.
Тут довольно такой... «грязный хак» используется. Дело в том, что gcc работает с некими TU (translation units). Указывая extern мы ему говорим что это не инлайн ни фига, а некий внешний TU. В этом случае эта TU будет в глобальной зоне видимости. Без указания extern, если мы глянем на таблицу экспортируемых символов, то ни чего там не увидим. С квалификатором extern ф-я будет экспортирована и доступна из любого места программы. В этом случае линкер (ld) найдёт её без труда.
Иначе, если мы определяем ф-ю как inline, то её адрес без оптимизации не будет определён (она же не подставляется). Чаще всего пофиг какая это ф-я инлайн или нет, её адрес должен оставаться неизменным. А тут у нас просто нет подстановки. Линкер не знает на что ему ссылаться, так что вот Вам и прилетела ошибка линковки.
Всё логично, в принципе.
Ещё добавлю что для версии, собираемой с -О0 можно использовать флаги gcc типа -fkeep-inline-functions и -fgnu89-inline. Но я не проверял их работу.
UPD. Само по себе поведение ф-ий inline описано в стандарте http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf (ISO/IEC 9899:1999б, раздел 6.7.4).
Исходная версия
Moisha_Liberman,
:
Если коротко...
А что даёт «extern inline»?
И почему не линкуется, если после препроцессинга все недостающие функции всё равно оказываются в файле?
Идея inline ф-ий заключается в их подстановке при компиляции и линковке. При отсутствии оптимизаций gcc гонит всё «как есть» линкеру, не выстраивая оптимизированную таблицу перекрёстных ссылок. При отсутствии оптимизаций (-О0 же!) ни каких оптимизаций не производится и инлайнинга тоже. Ф-я не подставляется без оптимизаций.
Тут довольно такой... «грязный хак» используется. Дело в том, что gcc работает с некими TU (translation units). Указывая extern мы ему говорим что это не инлайн ни фига, а некий внешний TU. В этом случае эта TU будет в глобальной зоне видимости. Без указания extern, если мы глянем на таблицу экспортируемых символов, то ни чего там не увидим. С квалификатором extern ф-я будет экспортирована и доступна из любого места программы. В этом случае линкер (ld) найдёт её без труда.
Иначе, если мы определяем ф-ю как inline, то её адрес без оптимизации не будет определён (она же не подставляется). Чаще всего пофиг какая это ф-я инлайн или нет, её адрес должен оставаться неизменным. А тут у нас просто нет подстановки. Линкер не знает на что ему ссылаться, так что вот Вам и прилетела ошибка линковки.
Всё логично, в принципе.
Ещё добавлю что для версии, собираемой с -О0 можно использовать флаги gcc типа -fkeep-inline-functions и -fgnu89-inline. Но я не проверял их работу.