C угловой корпус и ловушка - PullRequest
3 голосов
/ 01 сентября 2010

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

short main [] ={};

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

Ответы [ 3 ]

4 голосов
/ 01 сентября 2010

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

3 голосов
/ 01 сентября 2010

Вы получаете такую ​​ошибку?

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
1 голос
/ 01 сентября 2010

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

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

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

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

...