|
Модератор
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
|
|
inline в Си02.03.2019, 11:50. Показов 14412. Ответов 10
Метки нет (Все метки)
вопрос возник из этой темы Error: L6218E: Undefined symbol
сначала я предположил что у автора не подключен файл но потом я увидел проект и понял что не прав косяк именно в inline если использовать static inline, то все в порядке вопрос: Почему при использовании два и более раз inline функции линкер говорит что функция(имя) не определена?
0
|
|
| 02.03.2019, 11:50 | |
|
Ответы с готовыми решениями:
10
GCC Inline Assembly перевести в Visual Studio Inline Assembler Inline функции - на сколько должна быть маленькая функция, чтоб она подошла под inline? inline функции vs инструкции inline функций |
|
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
|
|||||||||||||||||
| 02.03.2019, 13:00 | |||||||||||||||||
static inline - явно установит linkage (как это нормально по-русски? связанность как-то криво...) функции в internal. еще вариант добавить в .h декларацию
0
|
|||||||||||||||||
|
Модератор
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
|
|||
| 02.03.2019, 13:48 [ТС] | |||
![]() и никаких внешних нет
0
|
|||
|
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
|
|||
| 02.03.2019, 14:05 | |||
|
0
|
|||
|
Модератор
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
|
|||||||
| 02.03.2019, 14:21 [ТС] | |||||||
|
никогда с этим не сталкивался, поскольку inline в си не пользовался вот такой код
хотя единица трансляции точно одна в общем поэкспериментирую и скажу
0
|
|||||||
|
|
|
| 02.03.2019, 15:07 | |
|
Вообще в разных диалектах Си ключевое слово inline трактуется по-разному: http://www.greenend.org.uk/rjk/tech/inline.html, причём отлично от Си++
Вероятно, в вашем случае речь идёт о C99 Добавлено через 6 минут В таком случае следует добавить в компиляцию ещё один модуль, в котором тело функции объявлено без inline Логика этого хозяйства примерно такая, что в хидер помещается функция с телом и inline'ом, а в библиотеку - функция с телом, но без inline. Описание из хидера трактуется как "это описание внешней фукнции, но если компилятор готов выполнять inline, то вот вам копия тела функции, оригинал реализован где-то в другом месте". В итоге компилятор в режиме без inline трактует такую конструкцию как "extern inline функция", а в режиме с inline - грубо говоря, как "static inline функция" В Си++11 есть аналогичная конструкция - это extern template
3
|
|
|
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
|
|||||||||||||||||||||
| 02.03.2019, 22:24 | |||||||||||||||||||||
|
Осталось объяснить почему так. Я постараюсь писать как-можно проще, но не для полных "чайников" и опущу аспекты касающиеся только переменных. ТС может читать со связывания.
Зайдем издалека ![]() Область видимости Обычно под этим понятием рассматривают глобальные и локальные переменные. В контексте темы областью видимости, если не указанно явно, следует считать "единицу трансляции". Локальная - текущий файл, глобальная - какие-то другие неподключаемые через #include файлы. Что такое декларация(в русских книжках тут иногда говорят "объявление", но мне не нравится) и определение функции Декларация задает как минимум имя функции и тип возвращаемого значения.
Деклараций одной и той же функции может быть много, но в пределах одной области видимости они не должны противоречить друг другу. Определение же ф-ции, это среди прочего "выделение памяти" под тело функции. Т.е это, то, что мы пишем с фигурными скобочками.
Если не делать разницы между .c и .h файлами (ее и на самом деле нет). То варианта только два: 1. В глобальном пространстве файла. 2. В блоке {} Где можно поместить определение функции Только в глобальном пространстве файла. (Нестандартные расширения языка типа nested functions в gcc мы не рассматриваем) Что такое связывание (linkage) Это процесс (этап компиляции), позволяющий установить, что несколько разных деклараций ссылаются на одно и то же определение. Существует 2 типа связей (на самом деле 3, но none для функций не применимо): 1. внешнее (external) - все такие декларации, даже распложенные в разных .c файлах ссылаются на одну и ту же функцию. 2. внутренне (internal) - в рамках одного .c файла. Как задается тип связи. Для ф-ций существует 2 варианта 1. static - внутренне связь 1.1 Попытка переопределить предыдущую extern декларацию - ошибка. 1.2 Можно использовать только в глобальном пространстве .c файла (т.е. внутри блока функцию можно декларировать только как extern) 2. extern - внешняя связь. 2.1 Выигрывает static: Если в области видимости текущей декларации есть более ранняя декларация с явным static - то связывание останется внутренним, ошибки не будет. 2.2. Если в области видимости текущей декларации нет более ранней, или есть, но без явного указания связывания - то связывание будет внешним. Если функция декларирована без явного указания класса - связывание внешнее. inline Это просьба компилятору сделать вызов функции как можно более быстрым. Прислушается ли он, и если да, то как именно это будет сделано - в общем случае неизвестно. На практике, компилятор либо подставит тело функции в нужное место, либо оставит все как есть. главное (откуда баг)
Не по теме: Прошу прощения за сумбурность - отвлекался несколько раз в процессе написания сего опуса.
1
|
|||||||||||||||||||||
|
|
|||
| 03.03.2019, 13:12 | |||
Сообщение было отмечено ValeryS как решение
РешениеА если посмотреть на первое из двух "либо" (либо иметь определение без inline для такой функции в текущем файле), то это, строго говоря, не верно. Если в текущем файле будет определение функции без inline, то оно попросту отменит декларацию с inline'ом, а вовсе не дополнит, как могло бы показаться на первый взгляд C /* Файл t1.c */ #if 1 /* Это то, о чём шла речь в изначально озвученной проблеме */ inline int inline_foo (int a, int b) { return (a + b); } #else /* Это аналог первого "либо" из твоей трактовки. Но он совсем не равнозначен * вышеидущему варианту. Он равнозначен варианту, когда inline декларация * попросту отсутствует */ inline int inline_foo (int a, int b); int inline_foo (int a, int b) { return (a + b); } #endif int main (void) { return inline_foo (1, 2); } C /* Файл t2.c */ /* Это вспомогательная функция, при помощи которой * мы проверяем корректность кода из первого файла */ int inline_foo (int a, int b) { return (a + b); } Code $ gcc-7.3.0 t1.c t2.c -std=c99 -fno-inline <ok> Code $ gcc-7.3.0 t1.c t2.c -std=c99 -fno-inline /tmp/cchQK5rf.o: In function `inline_foo': t2.c:(.text+0x0): multiple definition of `inline_foo' /tmp/ccpDJXSE.o:t1.c:(.text+0x0): first defined here collect2: error: ld returned 1 exit status Добавлено через 54 минуты Вышеидущий пример вместо опции "-fno-inline" можно скомпилировать с "-O3 -finline". Чтобы быть уверенным в том, что всё остаётся так же, независимо от того, выполняет компилятор inline-подстановки, или нет
1
|
|||
|
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
|
|||
| 03.03.2019, 13:45 | |||
|
Обязаны определить эту функцию (inline без указания типа связи)в текущем файле не меняя ее связанность. Такая функция не создаст "outline" (как правильно обозвать альтернативу inline???) версию, но создаст внешнюю связь с "outline" версией существующей где-то в другом файле.
0
|
|||
|
|
|||||
| 03.03.2019, 14:14 | |||||
|
Упоминание о таких просьбах можно встретить в учебниках 70-80-х годов, когда действительно такая просьба имела место быть - из-за маленького количества памяти компиляторы были слабенькими, а потому многих вещей не могли делать без дополнительных подсказок. Потом памяти стало больше, компиляторы поумнели, такая надобность отвалилась. В первом официально стандарте Си вообще не было никакого inline'а. В языке C++ задействовали ключевое слово inline, но под другой смысл, а во многих учебниках по прежнему писали старую трактовку inline'а, потому как большинство афторов учебников и сами толком не знали, зачем оно нужно (а срубить денег хотелось). Я совсем не удивлюсь, если окажется, что и в наше время приличная доля преподавателей в школах/институтах до сих пор не знают истинную семантику слова inline в современных стандартах языков Си и Си++
0
|
|||||
|
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
|
|||
| 03.03.2019, 15:40 | |||
|
0
|
|||
| 03.03.2019, 15:40 | |
|
Помогаю со студенческими работами здесь
11
inline Inline li
#define VS inline inline - функции Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ *
Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях.
Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её.
Последовательность действий:. . .
|
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
|
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение.
И на уровне агентов добавится между грибами или бактериями взаимодействий.
До того я пробовал подход через многомерные массивы,. . .
|
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Налог на собак: https:/ / **********/ gallery/ V06K53e
Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf
Пост отсюда. . .
|
|
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop?
Ниже её машинный перевод.
После долгих разбирательств я наконец-то вернула себе. . .
|
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод
Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод.
Thinkpad X220 Tablet —. . .
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|