понедельник, мая 21, 2007

Может ли main возвращать void

Вообще по Стандарту C++ функция main обязана возвращать int. Насколько мне известно, так же обстоят дела и в Стандарте С. И объявление функции main как void main формально ведет к undefined behavior. Тем не менее, main очень часто объявляют как void, особенно в синтетических примерах, код при это генерируется нормально. В принципе, объявление main как void может привести к проблемам, в частности код может получиться непортируемым.
Возвращаемый результат функции main иногда становится предметом вялых религиозных споров. Лично я чаще объявляю void main.

Ссылки по теме:
Can I write "void main()"? Страуструп в своем FAQ'e рассказывает, что объявлять main как void некорректно

17 коммент.:

Alexey Zakhlestin комментирует...

а зачем делать его void? всё-таки это как-никак способ сигнализировать ОС (или запускающему скрипту) об удачности или неудачности выполнения программы…

вот тут, кстати, есть разбор стандартов по этой теме: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1044841143&id=1043284376

Alena комментирует...

а зачем делать его void?

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

norguhtar комментирует...

Насколько я помню достаточно поставить return 1 или вообще ничего не возвращать. gcc же при определении void main сругнется, но скомпилит.

Alex комментирует...

чтобы вообще не задумываться о возвращаемом значении и сосредоточиться на том аспекте для которого этот пример пишется.

Как правило начинающие пользователи как раз учатся на этих примерах и привыкают к тому, что возвращать совершенно не обязательно. А потом они пишут программы, которые ничего не возвращают. И как в этом случае должна работать конструкция

$ newprog && echo ok

или

$ newprog || echo false

?

Alex комментирует...

gcc же при определении void main сругнется, но скомпилит

$ cat test.cpp
void main()
{
}

$ g++-3.3 test.cpp
test.cpp:2: error: `main' must return `int'
$ g++-3.4 test.cpp
test.cpp:2: error: `main' must return `int'
$ g++-4.0 test.cpp
test.cpp:1: error: '::main' must return 'int'
$ g++-4.1 test.cpp
test.cpp:1: error: '::main' must return 'int'
$ g++-2.95 test.cpp

только старые версии компилятора проглотят такое

Alena комментирует...

Как правило начинающие пользователи как раз учатся на этих примерах и привыкают к тому, что возвращать совершенно не обязательно.

Все же учиться только на синтетических примерах не есть хорошо. Обычно там слишком много допущений помимо возвращаемого значения функции main.

Насколько я помню достаточно поставить return 1 или вообще ничего не возвращать.
Кстати, да. Можно написать int main и вообще ничего не возвращать. Там по умолчанию return 0 по Стандарту.

Niraxoid комментирует...

...чтобы вообще не задумываться...и сосредоточиться...

Неужели int отвлекает больше чем void? Даже букв меньше :Р,
в примере можно в конце поставить:


// Комментарий,
// в котором будет все ясно.
return 0;

Yaroslav комментирует...

Фундаментальный вы вопрос затронули, барышня. А вообще может, да, сам видел!

Анонимный комментирует...

Да какая разница? Тяжело написать int и return 0? Не понимаю я вас. =\

PS: Не помню себя ни разу, чтобы писал void main.

aca комментирует...

There is a reason why C assumed that every function returns int, unless specified otherwise: it's the cheapest way to pass the value to the caller. On practically any implementation, return value is in the register. If the caller doesn't use the return value, it doesn't cost him anything.

Now, once you know this, you can see that the most convenient error handling mechanism in C is by using return values.

Now "main" is the function that is called by the run time library which is called by the operating system. And RTL and OS have its declaration as int main no matter how you declare main in your text.

So int main is expected to signal to the caller if the program execution was succesfull. If you don't return anything, the caller will get the garbage, whatever was in the register at the moment of the return.

So you should really get used to this idiom. It's very convenient too. Typically 0 means "everything ok" and other values specific error codes. Take a look at the simplest example:

f1 = fopen(
if ( !f1 ) return 1;
f2 = fopen(
if ( !f2 ) { fclose( f1); return 2; }
...
return 0;

(Off topic: Thanks for a very good blog, I often find interesting stuff here)

Анонимный комментирует...

int i = 5;
i = ++i + ++i;
Вопрос: Чему равно i?

Alena комментирует...

int i = 5;
i = ++i + ++i;
Вопрос: Чему равно i?


Этот код с bash.org.ru пользуется популярностью, я смотрю :-)

Не знаю, правда, как это соотносится с возвращаемым значением функции main, но ответ здесь.

PegasResearch комментирует...

Несомненно, корректно возвращать int, а void использовать некорректно - так утверждает стандарт, и с этим не поспоришь. Некоторые компиляторы считают void main синтаксической ошибкой. Но посмотрим, к чему приводит указание void в компиляторах, где это возможно.

Предполагаю, что в большинстве компиляторов функция main возвращает int вне зависимости от того, как объявить её у себя в программе - так как функция main вызывается кодом, стартующем программу, а код этот в большинстве компиляторов берётся из библиотеки. И в этой библиотеке main считается возвращающей int. Соответственно, и после вызова main стартующий код хочет получить (и получает) код возврата (на х86 как правило, содержимое AX/EAX).

Соответственно, объявив void main мы в результате выполнения программы вернём операционной системе случайное число (в данном контексте - неизвестное). Вот поэтому компилятор и пишет варнинги... Узнать, так это или нет просто - достаточно посмотреть, какие значения возвращают системе скомпилированные с void программы.

Анонимный комментирует...

Можно вообще написать

int main(void)

Если уж на то пошло.

Анонимный комментирует...

А что будет значить int main(int argc, char *argv[]), ну скажем, в программе для ATMega16?

Анонимный комментирует...

это таки отдельная тема... Вы не согласны?

Leo комментирует...

Здесь выше камент один: "Предполагаю, что в большинстве компиляторов функция main возвращает int вне зависимости от того, как объявить её у себя в программе..."
Так оно и есть. Когда пишут void main(), имеется в виду как бы аналог процедуры в Паскале, т.е. функции, которая ничего не возвращает. По идее, main - это не процедура, т.к. она возвращает код завершения EXIT_SUCCESS, который обычно равен нулю, если завершилось успешно.