Вы получаете ошибку?
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
флагом ССАГПЗ, что дает предупреждение:
<stdin>:1: warning: ‘main’ is usually a function
Я уверен, что видел этот уже, вы объявляете внешний символ основного и компоновщик Безразлично Не заботьтесь о типе. Это неверно. C. – jbcreix
-1 на вопрос спрашивает, почему какой-то смешной код с неопределенным поведением «работает» (в очень извращенном смысле хуже, не меньше). –
Я полагаю, кто-то должен упомянуть об этом [запись IOCCC] (http://www.ioccc.org/years.html#1984_mullender). –