Может ли кто-нибудь объяснить имена внутренних/внешних переменных?
В книге C говорится:
По крайней мере, первые 31 символа внутреннего имени являются значительными. Для имен функций и внешних переменных число может быть меньше 31, поскольку внешние имена могут использоваться ассемблерами и загрузчиками, над которыми язык не имеет контроля. Для внешних имен стандарт гарантирует уникальность только для 6 символов и одного случая. Ключевые слова, такие как if, else, int, float и т.д., Зарезервированы: вы не можете использовать их в качестве имен переменных. Они должны быть в нижнем регистре.
Может ли кто-нибудь объяснить, что такое "внутреннее имя", "внешние имена", "внешние переменные"?
Было бы лучше, если бы вы могли привести пример.
Ответы
Ответ 1
Поглаживая мою белую бороду и говоря в мудреце и помпезном голосе, я говорю:
В прежние времена, когда FORTRAN и COBOL управляли вычислительным миром, язык выскочек C должен был соответствовать существующим целям инструментов. Эти цепочки инструментов включали ссылки-редакторы (a/k/a линкеры, загрузчики a/k/a) и ассемблеры, которые обрабатывали только короткие 6-символьные символы (переменные и функции).
Компиляторы C для этих цепей инструментов должны были притворяться, что имена переменных и функций были короткими, когда они записывали объектные файлы, которые будут потребляться редакторами ссылок. Это была плохая новость. Хорошей новостью было то, что в программах C есть много символов, которые не должны отображаться в объектных файлах.
Например, имена функций... например. "main" и "sqrt"... должны отображаться в объектных модулях, поэтому код из других объектных модулей может их использовать. Так назывались глобальные переменные типа "extern". Это внешние имена.
Но все остальные имена в программе на языке C, например имена переменных в области функций, имена членов структур и т.д., не должны были попадать в объектные модули. Они называются "внутренними именами".
Итак, например, вы можете иметь эти переменные C внутри функции
int myFavoriteItem;
int myFavoriteThing;
и это будет хорошо. Но вы можете объявить их как внешние переменные, например:
extern int myFavoriteItem;
extern int myFavoriteThing;
Некоторые системы будут записывать эти имена в объектные файлы, как если бы они были длиной шесть букв (потому что объектные файлы не знали, что делать с более длинными именами). Затем они будут искать объектный файл, как будто они были объявлены следующим образом.
extern int myFavo;
extern int myFavo;
Это будут повторяющиеся декларации. Компилятор C должен был поймать подобные вещи и выбросить ошибку, а не написать дублирующее объявление в объектный файл. Это была отличная помощь программистам: дублировать объявления в объектных файлах, создавая по-настоящему непонятные сообщения об ошибках редактора ссылок.
В приведенном вами отрывке указано, что компиляторы должны распознавать не менее 31 символа внутреннего имени и 6 внешнего имени. Современные компиляторы и инструментальные цепочки больше не имеют разных ограничений длины имен.
Ответ 2
Внешние имена:
"Внешние" имена - это те, которые видны другим единицам компиляции, например нестатические функции и переменные, объявленные с ключевым словом "extern". Эти имена должны быть доступны для компоновщиков и загрузчиков. В Ye Olden Days некоторые линкеры и загрузчики могли обрабатывать очень короткие имена.
Внутренние имена:
"Внутренние" имена - это те, которые не отображаются за пределами компилируемого модуля - в основном что-либо с "статической" областью или что-то локальное для функции. Компиляторы C должны обрабатывать эти имена, но не что-то еще
Ответ 3
"Внутренние имена" - это имена идентификаторов внутри функции (фактически локальные имена переменных).
"Внешние имена" будут именами других идентификаторов, включая имена функций и любые идентификаторы, объявленные в глобальной области действия или объявленные с классом хранения extern.
В принципе, все, что должно быть "внешне видимым", гарантировано только 6 уникальными уникальными символами (не чувствительными к регистру), что крайне ограничено.
На практике это уже не проблема. C99 увеличили эти ограничения, и большинство современных компиляторов отменили или значительно увеличили эти пределы. Например, Visual С++ допускает 247 символов для уникальности во всех идентификаторах (внутренних или внешних) при компиляции C.
Ответ 4
Внешнее имя - это идентификатор с внешней связью. Для того чтобы идентификатор имел внешнюю связь, он должен быть либо нестационарным, либо специфическим объявлением "extern". Пример:
int global_variable;
int main(void)
{
int local_variable;
extern int extern_variable;
return 0;
}
В приведенном выше примере идентификаторы global_variable
и extern_variable
являются внешними именами. local_variable
- внутреннее имя.
Обратите внимание, что на практике количество значимых символов больше, чем 31 и 6. Компилятор Microsoft C, например, по умолчанию использует 247 значащих символов как для внутренних, так и для внешних имен. GCC рассматривает все символы внутренних имен как значимые. Значимые символы внешних имен зависят от компоновщика (а на большинстве платформ применяется то же правило, что и для внутренних имен, все символы значительны.)
В стандарте ANSI просто указывается минимальное количество значимых символов для стандартного соответствия реализации.