Почему main () нельзя объявить статическим в C?

Почему main должен быть объявлен так, как будто он имеет внешнюю ссылку?

Почему он не должен быть статичным?

Что подразумевается под внешней связью ??

Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
9
0
2 067
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку вы связываете файлы запуска со своей программой, которая содержит (обычно) код ассемблера, вызывающий ваш main. Если бы main был статическим, этот код не мог бы вызывать main.

External linkage означает, что другой так называемый translation-units может видеть ваш символ, объявленный как extern, в его собственной единице перевода. Итак, ваш main - это extern, и у него будет запись в таблице символов единиц перевода, в которой указан его адрес. Затем другие единицы трансляции смогут перейти на этот адрес, когда захотят вызвать main.

Static linkage означает, что ваш символ является строго локальным для единицы перевода. Это означает, что другой translation units не сможет увидеть этот символ. Таким образом, символы со статической связью могут встречаться в разных единицах перевода несколько раз, и они не будут конфликтовать друг с другом, потому что они локальны.

Редактировать: Как правило, файлы, созданные компилятором из единиц перевода, специфичны для этого конкретного компилятора. Для gcc в Linux часто используется объектный формат ELF. Вы можете просмотреть его таблицу символов с помощью readelf -sW <file>.o (простой тестовый файл ниже):

Test.c

void bar(void);

static int foo(void) {
    return 1;
}

int main(void) {
    bar();
    return foo();
}

Вот результат работы readelf:

Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000    10 FUNC    LOCAL  DEFAULT    1 foo
     6: 00000000     0 SECTION LOCAL  DEFAULT    6
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 0000000a    36 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar

Вы видите функцию main и статическую функцию foo, вызываемую main. Также вызывается функция, которая не определена в файле, но определена в другом объектном файле. Поскольку объектный файл еще не был окончательно связан, функциям еще не назначены окончательные адреса. После последней ссылки они будут упорядочены в исполняемый файл, и им будут назначены адреса. В объектном файле есть записи для вызовов еще не определенных функций, так что, когда файл связан, эти инструкции вызова могут иметь сохраненные конечные адреса (readelf -r <file>.o):

Relocation section '.rel.text' at offset 0x308 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001c  00000902 R_386_PC32        00000000   bar

Как мы можем проанализировать эти единицы перевода. Можем ли мы увидеть их в виде таблиц или графических форм для каждого файла? Если это невозможно, то в каком файле, созданном компилятором, или файле атрибутов, мы можем узнать атрибут функции.?

Manoj Doubts 26.11.2008 15:05

У вашего поставщика инструментов будет служебная программа, которая сделает это. Например. objdump (Unixy), dumpbin (MSFT), tdump (Borland / CodeGear / Embarcadero)

Barry Kelly 26.11.2008 15:09

Хорошо, хорошо, спасибо, ребята, за ваши объяснения. Это очень помогло мне узнать

Manoj Doubts 26.11.2008 15:25

Отличный ответ. Очень понравилось

Namratha Patil 27.11.2008 13:04

Также есть «nm» для Unix. objdump более мощный инструмент, но вам нужно понимать его параметры.

quark 17.02.2009 00:12

Настоящая отправная точка кода похоронена в библиотеке времени выполнения C. Эта библиотека времени выполнения вызывает вашу подпрограмму main (). Чтобы компоновщик мог связать вызов C RTL с вашей функцией main (), он должен быть видимым вне файла.

Внешняя связь такова: это означает, что рассматриваемое имя отображается как часть экспорта объектного файла. Задача компоновщика - объединить весь импорт и экспорт, чтобы не было невыполненных операций импорта.

Другие вопросы по теме