Andrei
Да
Andrei
Потому что функции всегда по дефолту и так имеют внешнюю линковку
Ned
Ну опять же. Нахуй тогда extern?
Andrei
Но можно сделать её внутренней клбчевым словом static или помещением в анонимный неймспейс.
Andrei
В смысле? Extern для переменных.
Ned
Ned
авто stdio.h тоже так считает)
Andrei
Блин
Andrei
Я понял
Andrei
Тут в другом делом
Andrei
Тут дело в том, как линкеру искать зависимости.
Andrei
Смотри.
Ned
Да, я тут, слушаю внимательно
Andrei
Дело в порядке объявления функций.
Andrei
Как я уже сказал есть слово static
Andrei
extern будучи объявлен после static не имеет никакого эффекта
Andrei
Просто extern излишен
Andrei
Но вот объявленная static функция после объявления extern вызовет ошибку линковщика
Andrei
То есть если мы где-то объфвили функцию как extern
Andrei
Далее мы уже не можем её переобпределить
Andrei
Но вообще никакого смысла использовать extern с функциями нет.
Andrei
Это делается по историческим причинам. Привычка.
Andrei
Просто явное указание читающему код что функция реализована где-то еще а не здесь.
Ned
Объясни, плз, разницу внешней и внутренней линковки
Andrei
Там есть еще второе значение extern но это уже про inline
Andrei
Эм. Ну смотри.
Andrei
Компилятор делает тебе объектные файлы.
Andrei
Объектные файлы содержат функции и переменные.
Andrei
Если например у тебя есть переменная или функция в одном файле которая сслыается на переменную или функцию из того же файла то это внутренняя линковка
Andrei
Если она ссылается на функцию или переменную которая определена в другом файле то это внешняя.
Andrei
Вот и все
Andrei
Ты разницу между объявлением и определением понимаешь?
Ned
то есть если функция объявлена в cpp static, то извне её уже не вызовешь?
Andrei
Да.
Andrei
Линкер её не найдет.
Ned
из другого срр даже если их слинковать вместе?
Andrei
Да.
Andrei
Потому что помеченные static функции не выносятся в таблицу экспорта.
Andrei
Которую просматривает линкер
Ned
почему бы тогда не static int main()?
Andrei
Можешь так написать.
Andrei
Все будет ок.
Ned
хотя как тогда её вызовет система?
Ned
а хотя нормально
Ned
точкой входа-то она останется
Andrei
Только хотя бы в одном файле должно быть не static main
Andrei
Не останется. Линкер не поймет.
Andrei
Хотя бы в одном файле должна быть int main без слова static
Andrei
Линкер это и есть то, что делает main точкой входа.
Andrei
(Не совсем так но понимать можно именно так)
Ned
ну есть ещё какая-то ф-я __start
Ned
ее линкер и вытаскивает как точку входа
Ned
или нечто в этом роде
Andrei
Ну да. Там еще генерируется вокруг обычно некий код.
Andrei
Инициализационный/деинициализационный
Ned
ну да, он обрамляет это всё
Andrei
Ага. Но внутри этой ___start есть вызов main
Andrei
Которую линкер попытается найти.
Ned
дада, это я где-то читал
Ned
как тогда понять extern "C" {...}?
Andrei
А. Это совсем другое
Andrei
Это связано с экспортом.
Andrei
Смотри.
Ned
блять
Stanislav
Ned
ща кто-т запутается к чертям и это буду я
Ned
ну ладно
Andrei
Вот ты написал в сишном файле функцию int foo(void);
Andrei
А потом в другом файле ее заюзал
Andrei
Как эта магия работает?
Ned
линкер нашел, залинковал
Ned
статически, кстати, походу
Andrei
Когда компилятор компилирует первый файл в объектник
Andrei
Он пишет таблицу
Stanislav
давай уже про манглинг и ABI :)
Andrei
Таблицу экспорта
Andrei
В которой будет написанно следующее
Andrei
В этом файле есть функция с сигнатурой int foo(void)
Ned
ну имя, адрес и параметры, что логично
Andrei
И тода линкер прросматривая по порядку объектник. Её найдет