# Do NOT use "void main()" in C/C++

When I had the class 「Fundamental of Computer Science」 tonight, my teacher present a slide that writes void main(). I pointed out the mistake that main function's return type should be int in C/C++.

The father of C++ program language, Bjarne Stroustrup, once posted this on his personal website in column C++ Style and Technique FAQ.

C++ Style and Technique FAQ

Can I write "void main()"?

The definition
void main() { /* ... */ }
is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
A conforming implementation may provide more versions of main(), but they must all have return type int. The int returned by main() is a way for a program to return a value to "the system" that invokes it. On systems that doesn't provide such a facility the return value is ignored, but that doesn't make "void main()" legal C++ or legal C. Even if your compiler accepts "void main()" avoid it, or risk being considered ignorant by C and C++ programmers.

For instance, suppose we compile such C source code,

void main() {

}

will generate a warning

$gcc -o a Untitled.c Untitled.c:1:1: warning: return type of 'main' is not 'int' [-Wmain-return-type] void main() { ^ Untitled.c:1:1: note: change return type to 'int' void main() { ^~~~ int 1 warning generated. The compiler tell us that 'main' function should return 'int' instead of 'void'. Besides, the form void main() is not supported in C89 nor ANSI C (in fact, none of C/C++ standard support this form of declaration of main function ). And this is error in C89 and ANSI C. C89$ gcc -std=c89 -o a Untitled.c
Untitled.c:1:1: error: 'main' must return 'int'
void main() {
^~~~
int
1 error generated.

ANSI C

$gcc -ansi -o a Untitled.c Untitled.c:1:1: error: 'main' must return 'int' void main() { ^~~~ int 1 error generated. Let's go deep into assembly level. Modify the source file, int main() { return 1; } then execute$ gcc -S Untitled.c   and we can get Untitled.s.

The Content of Untitled.s

.section        __TEXT,__text,regular,pure_instructions
.globl    _main
.align 4, 0x90
_main:                                  ## @main
.cfi_startproc
## BB#0:
pushq        %rbp
Ltmp2:
.cfi_def_cfa_offset    16
Ltmp3:
.cfi_offset  %rbp,  -16
movq        %rsp,  %rbp
Ltmp4:
.cfi_def_cfa_register  %rbp
movl        $1, %eax movl$0,  -4(%rbp)
popq        %rbp
retq
.cfi_endproc

.subsections_via_symbols
We can see that

movl        \$1,  %eax

save the return value of main faction to eax.

If you declare main as void main(). Then the value in eax is completely a random value. It seems that this is ok when you execute your program. But it will be a fatal error.

If you do ./a && echo "YES"  in shell. Due to the return value of a is possibly not zero, so the command echo "YES" will not be executed even if your program is actually finished normally.

声明: 本文为0xBBC原创, 转载注明出处喵～