Что произойдет, если main() не возвращает значение int?
Я знаю, что в компиляторах C функция main()
вызывается функцией _start()
, которая имеет код примерно так:
exit(main()); // return value of main is returned
Как работает _start()
, когда main()
не возвращает int
, например, если его тип возврата void
, float
или что-то еще?
Ответы
Ответ 1
Если main
не возвращает int
, то у вас есть плохо сформированная программа, а поведение undefined. Все может случиться. Ваша программа может потерпеть крах, или она может работать, как будто ничего не случилось вообще.
Предположим, что main
возвратил нечто, отличное от int
, и ваш компилятор и компоновщик разрешили выполнение программы. Однако вызывающий не знает этого. Если вызывающий абонент ожидает возврата значений int
, которые будут возвращены в регистре EAX (Intel), то это будет считаться для определения возвращаемого значения main
. Если ваш неисправный main
сохранил там значение float
, тогда он будет интерпретироваться как int
. (Это не означает, что он будет усечен. Это означает, что биты, составляющие компоновку значения с плавающей запятой, вместо этого составляют вместо int
.) Если ваш ошибочный main
вернулся void
, то он didn 't хранить что-либо в ожидаемом регистре, так что вызывающий получит какое-то значение, ранее сохраненное в этом регистре.
Если ваш main
возвращает некоторый тип, который он ожидает сохранить где-то, что вызывающий не резервировал память (например, большую структуру), тогда она закончит перезаписывать что-то еще, возможно, что-то важное для чистого завершение работы программы, что приведет к сбою вашей программы.
Ответ 2
В стандарте C никогда не упоминается эта функция _start
; Я не верю, что С++ тоже.
В C до стандарта ISO 1999 года, если выполнение заканчивается main()
без выполнения оператора return
или выполняет оператор return
, который не указывает значение, тогда "статус завершения возвращается для среды хоста undefined". На практике я видел реализации, когда такая программа возвращает статус 1 (отказ) или какое-то произвольное значение в памяти, такое как результат последней вызванной функции.
Стандарт ISO ISO 1999 изменил это: "достижение", которое завершает функцию main, возвращает значение 0 ". Это соответствует правилу, которое С++ имеет по крайней мере с первого стандарта ISO С++ в 1998 году.
(В качестве стиля я предпочитаю иметь явный return 0;
в конце main
, даже если он строго не требуется. Это согласуется с int
функциями, отличными от main
, и это делает лучшую переносимость для компиляторов pre-C99 C.)
Все это предполагает, что main
определяется с типом возврата int
. Единственный тип, который специально поддерживается стандартом C (либо int main(void)
, либо int main(int argc, char *argv[])
или эквивалентный), но (размещенные) реализации, может поддерживать другие определения, определенные для реализации. В стандарте C90 явно не рассматривается этот случай, но C99 говорит: "Если тип возврата несовместим с int, статус завершения, возвращаемый в среду хоста, не указан".
Стандарт С++ немного отличается. Для размещенных внедрений main
должен быть определен для возврата int
. Параметры определяются реализацией, но должны поддерживаться как стандартные формы C.
Для размещенной реализации на C или С++ нет оснований для определения main
с типом возврата, отличным от int
. Просто используйте одно из двух стандартных определений, и вопрос не возникнет.
Для "автономных реализаций", "имя и тип функции, вызываемой в программе
startup определены в соответствии с реализацией ". Таким образом, точка входа может законно возвращать void
или что-то еще, и ее даже не можно назвать main
. Обратите внимание, что" автономная реализация "- это" одна ", в которой может выполняться выполнение программы C без всяких
преимущество операционной системы ", как правило, встроенная система.
Ответ 3
Функция вернет значение, определенное реализацией. Например, в С++ main
неявно возвращает 0
. В этом случае void
main это просто будет возвращено _start
. Тем не менее, практически нет реализаций, которые позволили бы любому произвольному типу возврата - он запекался в операционной системе, чтобы процесс выходил с интегральным значением.
Ответ 4
В С++ было бы компиляционной ошибкой возвращать что-либо кроме int
из main()
:
error: ‘::main’ must return ‘int’
В C это предупреждение, вы получите float, интерпретируемый как int
: например, 2.1F будет переинтерпретирован как 224.
Ответ 5
Стандартные реализации C ожидают main
для возврата int
только потому, что он определен таким образом в стандарте C. Возврат чего-то другого, кроме int
(или типа, совместимого с int
), обычно приводит к undefined behavior &mdash, что означает, что невозможно сказать, что произойдет.
Однако существуют нестандартные реализации C, например, в операционной системе Plan 9 используется void main()
, здесь - это список их утилиты исходный код. Код Plan 9 C совсем немного отличается от K & R, ANSI, C99 или C11. Вот ссылка, объясняющая, как Plan 9 использует язык C.
Ответ 6
Если тип возврата main
не является int
, тогда возвращаемое значение определяется реализацией.
Короче говоря, для реализации допускается иметь другой тип возврата, чем int
для main
, но ни одна из известных реализаций не поддерживает ничего, кроме int
.
В идеале, вам нужно будет обратиться к документации вашей платформы и компилятору, чтобы узнать, какое точное поведение оно определяет, потому что это позволяет иметь гибкость в соответствии со стандартом.
Ссылка:
С++ 03 Стандарт:
3.6.1 Основная функция [basic.start.main]
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь тип возвращаемого типа int, но в противном случае его тип определяется. Все реализации должны допускать оба следующих определения main:
int main() {/*... */}
и
int main (int argc, char * argv []) {/*... */}
.....
Ответ 7
C-standard не позволяет вам возвращать любое другое значение, чем int или void - c-компилятор специально тестирует подпись main, чтобы убедиться, что он совместим.
Ответ 8
Предположим, мы используем Visual Studio 2012.
Для программ на С++ Visual Studio позволяет указывать void
как возвращаемый тип, хотя это запрещено стандартом С++. В стандарте main()
должен возвращать int
в размещенных реализациях.
Для программ C любой тип возврата разрешен для main()
, но возврат чего-либо, отличного от int
, приводит к неуказанному поведению. Например, в Visual Studio 2012 возвращение 0.0
из double main()
приводит к возвращаемому значению 0xcccccccc
, когда программа запускается в отладчике (см. В Visual Studio С++, каковы представления распределения памяти?).