LINUX.ORG.RU

[C++]Предрассудки компилятора.

 


0

1

Уважаемые ЛОРовцы! У меня к Вам вопрос. Вот есть главная функция main() {...} , перед которой можно поставить int, в ней самой написать в конце return 0; и она вернет ноль. А можно поставить void, тогда она ничего не вернет. Но на void компилятор почему-то выдает предупреждение, что функция должна возвращать int. Скажите, для чего же нужно, чтобы главная функция выдавала именно int, или это абсолютно всеравно и компилятор просто страдает предрассудками?

Оболочка определяет код выполнения программы по возвращаемому значению main.

flareguner
()

Стандарта на C++ сейчас под рукой нет, но в стандарте C есть следующее:

5.1.2.2.1 Program startup
1   The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined manner.

eXire ★★
()
Ответ на: комментарий от BlacKeeper

>Извиняюсь, надо было нме сначала все-таки погуглить.

Нет. сначала нужно дочитать букварь

Led ★★★☆☆
()

Функция main() экспортируется из исполняемого файла без сигнатуры, только по имени. Вызывающий код всё равно приведёт её к прототипу (int*)(int,char**), подставит параметры и получит возвращаемое значение. Если в вашей программе она была определена как void main() - вызывающий код вернёт какой-то мусор из стека. Оттого и warning.

Вот вам пример на MinGW, думаю под Линуксом результат будет тот же. Максимум где может быть разница - в какую сторону смещаться относительно &argc, влево или вправо:

#include <stdio.h>

void main( int argc )
{
	char ** argv = *(char***)((char*)&argc + sizeof(argc));
	printf( argv[0] );
}

Запускаем:

D:\projects\tmp\voidmain\build>voidmain.exe
voidmain.exe
Dendy ★★★★★
()
Ответ на: комментарий от Boy_from_Jungle

> Во что превращается ЛОР?!

нужно чаще банить

korvin_ ★★★★★
()

who are all of these people?

anonymous
()
Ответ на: комментарий от Dendy

GCC выдаёт warning, но компилирует такой код, а вот clang более строг:

18:34 zloddey@zlaptop:/tmp/c$ cat 1.c 
#include <stdio.h>

void main(int argc)
{
	char ** argv = * (char ***) ((char*)&argc + sizeof (argc));
	printf (argv [0]);
}
18:34 zloddey@zlaptop:/tmp/c$ clang -o test 1.c 
1.c:3:1: error: 'main' must return 'int'
void main(int argc)
^
1.c:6:10: warning: format string is not a string literal (potentially insecure)
      [-Wformat-security]
        printf (argv [0]);
                ^~~~~~~~
2 diagnostics generated.
18:36 zloddey@zlaptop:/tmp/c$ clang --version
clang version 1.1 (branches/release_27)
Target: i386-pc-linux-gnu
Thread model: posix
18:37 zloddey@zlaptop:/tmp/c$ uname -a
Linux zlaptop 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:48:22 UTC 2010 i686 GNU/Linux

Zloddey
()
Ответ на: комментарий от Dendy

> Если в вашей программе она была определена как void main() - вызывающий код вернёт какой-то мусор из стека.

Результат возвращается в регистре, стек не при чем.

sjinks ★★★
()
Ответ на: комментарий от sjinks

Кстати, да.
Такую херню про стек сморозить это позор для C++ программиста.

Love5an
()
Ответ на: комментарий от sjinks

> Результат возвращается в регистре

Зависит от компилятора, соглашений вызова и размера возвращаемого значения. В случае x86 и int - да, вы правы, вернётся что-то из eax.

Dendy ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.