|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
Extern и функции с компоновкой по правилам языка С++12.10.2025, 12:32. Показов 2541. Ответов 20
Добрый день,
Разобрался с модульным построением программ (через пространства имен) и раздельной компиляцией, понимаю что в заголовочных файлах нужно объявлять переменные с модификатором extern, а определять их в единственном месте в соответствующем *.cpp файле. Пишу программы в таком стиле и они работают. Но не могу понять следующего: для чего и в каких функциях использовать extern при объявлении функции, компонуемых в соответствии с правилами языка c++. Тут не веду речь об extern "C", с ним то как раз все ясно. Мои программы прекрасно работают без extern функций, хотя активно использую и пространства имен, и раздельную компиляцию. Подскажите пожалуйста по сабжу, для чего нужен extern при написании обычных с++ функций?
0
|
|
| 12.10.2025, 12:32 | |
|
Ответы с готовыми решениями:
20
Что означает extern "C" или extern "C++"?
Какая разница между компиляцией и компоновкой? |
|
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
|
||
| 12.10.2025, 13:13 | ||
|
"Обычные" функции итак уже по умолчанию имеют external linkage specifier Поэтому, явное указание external для них никакого нового эффекта уже не окажет.
1
|
||
|
Вездепух
13200 / 6835 / 1822
Регистрация: 18.10.2014
Сообщений: 17,293
|
|||||
| 12.10.2025, 23:08 | |||||
|
Речь, очевидно, идет о глобальных переменных. Злоупотребление глобальными переменными - это уже серьезная стилистическая проблема, которая к тому же легко может эволюционировать в существенно более серьезные проблемы. Также, в современном С++ вы можете избежать дублирования объявлений (то есть обойтись без вот этого двойного "объявлять ... с модификатором extern, а определять ... в *.cpp файле") путем единственного объявления-определения в заголовочном файле с ключевым словом inline. Никакого extern не нужно. Никакого "определять в *.cpp файле" тоже не нужно.extern при объявлении функции в С++ не нужен никогда, за исключением этого самого варианта extern "C".extern, если вы явно не укажете иного. Поэтому явное указание extern не нужно.
1
|
|||||
|
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
|
||
| 12.10.2025, 23:51 | ||
|
1
|
||
|
Вездепух
13200 / 6835 / 1822
Регистрация: 18.10.2014
Сообщений: 17,293
|
|||||||
| 13.10.2025, 05:19 | |||||||
|
С самого начала времен (т.е. с С++98), если вам совсем не хотелось возиться с раздвоенными объявлением и определением глобальной переменной global_variable, у вас была возможность объявить в заголовочном файле
global_variable() в роли переменной. Это может выглядеть внешне странновато, но достигает требуемого эффекта.Ясно, что раз компилятор-линкер уже вынуждены решать задачу обеспечения единственности локальной статической global_variable_, то до просто inline-переменных, без необходимости функции-оболочки, остался совсем маленький шаг.
3
|
|||||||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|||
| 13.10.2025, 18:42 [ТС] | |||
|
Всем спасибо за понятные объяснения! Теперь у меня одним сомнением меньше:
extern в с++ функциях действительно не нужен!![]() inline?
0
|
|||
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|
| 13.10.2025, 18:58 | |
|
0
|
|
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
| 13.10.2025, 19:56 [ТС] | |
|
Не понятен ответ. Из него кажется что
inline в общем случае пользоваться не стоит. А использовать только в определенных случаях, так?? Я примерно так думал: inline для маленьких простых функций, замена макросам языка С. Т.е. никаких рекурсий, функций вызываемых по указателям. Хотелось бы понять, когда на практике использовать inline, а когда не стоит
0
|
|
|
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
|
||
| 13.10.2025, 21:20 | ||
|
Исторически, inline использовался в качестве подсказки компилятору, что нужно вставить тело функции прямо в место вызова, вместо генерации call (типа когда есть маленькая функция, которая часто вызывается). Но современные компиляторы неплохо оптимизируют код в -O2 и выше и не нуждаются в такой порнографии. А вот не нужно использовать для больших функций, т.к. это приведет к бинарному раздуванию кода. Для виртуальных функций обычно тоже не нужно использовать, т.к. там функции определяются через виртуальные таблицы.
0
|
||
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
||
| 13.10.2025, 22:38 | ||
|
Если inline это уже не про встраивания а про связывание, то при чем тут размер тела этой функции?
0
|
||
|
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
|
|
| 13.10.2025, 22:41 | |
|
0
|
|
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|||
| 13.10.2025, 22:50 | |||
|
Так и зачем? Если это потеряло актуальность уже достаточно давно?
0
|
|||
|
6241 / 2954 / 1047
Регистрация: 01.06.2021
Сообщений: 10,979
|
||
| 13.10.2025, 22:55 | ||
|
0
|
||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
| 14.10.2025, 01:24 [ТС] | |
|
Почитал Ваши ответы про
inline и запутался еще больше. Если inline теперь не про встраивание, то зачем он вообще нужен? Для чего нужны множественные определения, если достаточно раскидать объявления функций по пространствам имен в заголовочных файлах и сделать по одному определению в соответствующих *.cpp. И все будет четко и понятно, тем более в современных IDE на мониторах с большим разрешением?!
0
|
|
|
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
|
|||||||
| 14.10.2025, 02:13 | |||||||
|
Нужны не множественные определения, как таковые, а возможность определить функцию в заголовочном файле, который далее можно будет подключить к разным файлам.cpp без риска налететь на ошибку множественного определения. Например, вы разрабатываете HEADER_ONLY библиотеку, и вам позарез понадобилось специализировать шаблон. Благодаря inline specifier, вы сможете определить специализацию прям в заголовочном файле:
1
|
|||||||
|
Вездепух
13200 / 6835 / 1822
Регистрация: 18.10.2014
Сообщений: 17,293
|
||||
| 14.10.2025, 07:57 | ||||
inline нужен для того, чтобы можно было втыкать полное определение глобальной функции в каждый .cpp, но при это не получать ругани от линкера о множественном определении. Это же самое относится и к глобальным переменным.То есть, выражаясь просто и грубо, назначение inline - это "подавлять" классическое правило ODR, то есть давать вам возможность клепать множественные определения глобальных сущностей (в разных единицах трансляции) и при этот не получать ошибок линкера о множественных определениях. Вместо ругани линкер будет покорно и молча удалять лишние определения из финального кода, оставляя только одно.inline или нет. Если тело функции видно компилятору - то эта функция является кандидатом на встраивание.)Если же компилятор не видит полного определения функции в каком-то .cpp, то в этом .cpp он никак не сможет встроить данную функцию, а будет вынужден генерировать обычные вызовы и ждать, что линкер эти вызовы потом правильно разрешит. Таким образом, inline по-прежнему связан с встраиванием вызовов, но косвенно. Он не "запрашивает" встраивание (как было принято интерпретировать его назначение раньше), а лишь создает благоприятные условия для встраивания. А уже встраивать или нет - это компилятор решит сам на основе своих внутренних критериев.Дополнительно к поддержке встраивания функций, такая роль inline также позволяет вам создавать header-only библиотеки - еще одна ценная возможность inline, которая ценна и для переменных.
1
|
||||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
| 14.10.2025, 20:29 [ТС] | |
|
TheCalligrapher, спасибо за понятное объяснение. Можно я Вас еще порасспрашиваю?
![]() Я понимаю, что встраивание повышает быстродействие. Обратной стороной является увеличение кода. Учитывая доступные ресурсы современных вычислительных систем (не считая встраиваемых систем, микроконтроллеров и т.п., но там обычно чистый С или ассемблер) и то что непосредственно код занимает МАЛУЮ долю конечного программного продукта, наверное, целесообразно использовать встраивание максимально широко, насколько возможно. Прав я или нет? Отсюда вопрос, в каких случаев встраивание использовать не стоит??? Я вижу рекурсивные функции и функции вызываемые по указателям (т.к. на момент компиляции может быть не известно, какая конкретно функция может быть вызвана). Подскажите как оно на самом деле??
0
|
|
|
Вездепух
13200 / 6835 / 1822
Регистрация: 18.10.2014
Сообщений: 17,293
|
|||
| 14.10.2025, 21:00 | |||
|
Если нет, то вопроса "стоит или не стоит" для вас не существует. У вас нет контроля над встраиванием. Решения о встраивании (когда оно возможно) принимает компилятор, на основе своих внутренних критериев. Ваша задача - лишь не мешать ему в этом, по возможности. Поэтому то, как вы будете определять свои функции, в большинстве случаев будет обуславливаться совсем другими соображениями, к встраиванию никакого отношения не имеющими вообще. Например, если вы хотите скрыть реализацию каких-то типов данных и соответствующих функций, то вам придется определять все в .cpp файлах. Это приведет к тому, что соответствующие функции не будут встраиваться. Но такой подход, еще раз, был принят ради важной цели: сокрытия реализации, а встраивание или не встраивание здесь - вопрос десятый. Если же вы хотите написать header-only библиотеку, то получится наоборот: вся реализация окажется полностью открытой и все функции такой библиотеки будут потенциально встраиваемыми. Но, опять же, это решение было принято не ради встраивания, а ради удобства header-only библиотек. Встраивание здесь сбоку припеку. И только если у вас нет никаких других доминирующих соображений, диктующих способы определения функций, тогда можно прибегнуть к некоему нечеткому интуитивному делению функций на "большие" и "маленькие". Большие идут в . cpp файл, а маленькие - в . h файл с inline.Никто не запрещает компилятору встраивать несколько уровней вложенности рекурсивной функции (или даже все, если он точно знает сколько их будет). Никто не запрещает компилятору встраивать вызов через указатель, если он знает куда этот указатель указывает.
1
|
|||
|
1 / 1 / 0
Регистрация: 05.12.2024
Сообщений: 60
|
|
| 15.10.2025, 11:06 [ТС] | |
|
TheCalligrapher, как я понял из Вашего ответа, во главу угла ставится вопрос компоновки программы: где разместить тело той или иной функции
1) в заголовочном файле. тогда она inline и кандидат на встраивание.2) в *.cpp файле. тогда она "обычная" и может встраиваться только при вызове из того же *.cpp где она была объявлена. Другими соображениями голову можно не забивать. Спасибо.
0
|
|
| 15.10.2025, 11:06 | |
|
Помогаю со студенческими работами здесь
20
Extern: Есть ли на данный момент набор инструментов, которые позволили бы использовать другие языки Опишите функцию extern в Си, её аргументы, назначение и что возвращае Использование extern с функциями
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . .
а удачный момент так и не приходит.
|
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица.
Задача: зафиксировать три левых колонки в отчете.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
/ / . . .
|
Настройки VS Code
Loafer 13.04.2026
{
"cmake. configureOnOpen": false,
"diffEditor. ignoreTrimWhitespace": true,
"editor. guides. bracketPairs": "active",
"extensions. ignoreRecommendations": true,
. . .
|
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2.
Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива.
Было так:. . .
|
|
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: реализовать контроль корректности заполнения дат назначения. . .
|
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html
Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
|
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача №1: при указании работ (справочник РаботыПоРемонтуСпецтехники),. . .
|
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях.
Задача: при копировании документа очищать определенные реквизиты и табличную. . .
|