C угловой корпус и ловушка

Я удивлен, почему это работает?

short main [] ={};

Это единственный контент в файле. Он правильно компилируется на gcc. Но когда я бегу, это печатает ошибку сегментации. Когда я переименовываю main, компилятор выдает ошибки. Может кто-нибудь объяснить мне, что здесь происходит.

3 ответа

Очевидно, компоновщик не знает тип глобальных объектов (таких как: переменная или функция), но только адрес; поэтому он связывает программу, как если бы ваша переменная была функцией. Который вылетает по понятным причинам.

Вы получаете ошибку, как это?

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Это не ошибка компилятора, а ошибка компоновщика.

При компиляции каждый исходный файл преобразуется в объектный файл.

Нет проверки int main() существует, потому что программа может состоять из нескольких источников, и main() определяется только в одном из них или даже не должен существовать (например, в динамической библиотеке). Поскольку источник

short main[] = {};

считается действительным объявлением (создать глобальный short названный массив main и инициализировать в пустой массив) компилятором, он не будет генерировать никаких ошибок.

Обнаружение того, int main() существует проверяется компоновщиком. Компоновщик связывает скомпилированные объектные файлы с рабочим исполняемым файлом. Если компоновщик не может найти символ main, он будет жаловаться, как тот, который я описал выше. К сожалению, обычный C ABI не различает функции или виды экспортируемых переменных. Так что даже если main объявлен как массив, так как компоновщик знает только то, что называется main существует "и не может проверить больше, оно также пройдет.

В результате программа создается без ошибок, хотя она написана неправильно.

Когда программа запускается, так называемый main не содержит исполняемый код Скорее, это просто некоторые данные (вероятно, обнулены). Таким образом, система может сделать что-нибудь неожиданное (в вашем случае это SEGFAULT).

Это на самом деле может быть обнаружено при компиляции с -Wall флаг в gcc, который выдает предупреждение:

<stdin>:1: warning: ‘main’ is usually a function

Попробуйте скомпилировать с большим количеством опций.:)

Например, добавив простой -Wall

gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function

Я не читал соответствующую стандартную страницу, но, видимо, для компиляции нужно просто иметь main, а не обязательно функцию...

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