Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ‘int main;’ a valid C/C++ program?

I ask because my compiler seems to think so, even though I don’t.

echo 'int main;' | cc -x c - -Wall
echo 'int main;' | c++ -x c++ - -Wall

Clang issues no warning or error with this, and gcc issues only the meek warning: 'main' is usually a function [-Wmain], but only when compiled as C. Specifying a -std= doesn’t seem to matter.

Otherwise, it compiles and links fine. But on execution, it terminates immediately with SIGBUS (for me).

Reading through the (excellent) answers at What should main() return in C and C++? and a quick grep through the language specs, it would certainly seem to me that a main function is required. But the verbiage from gcc’s -Wmain (‘main’ is usually a function) (and the dearth of errors here) seems to possibly suggest otherwise.

But why? Is there some strange edge-case or “historical” use for this? Anyone know what gives?

My point, I suppose, is that I really think this should be an error in a hosted environment, eh?

like image 978
Geoff Nixon Avatar asked Jan 05 '15 09:01

Geoff Nixon


People also ask

Is Main () valid in C?

No. It's non-standard. The standard prototype of main is int main() with the optional command line arguments argc and argv . The int returned by main() is a way for a program to return a value to the system that invokes it.

What is int main () in C?

int main represents that the function returns some integer even '0' at the end of the program execution. '0' represents the successful execution of a program. The syntax of int main is as follows − int main(){ --- --- return 0; } int main(void) represents that the function takes NO argument.

Is int main () a function call?

Difference between int main() and void main() and main() Like any other function, main is also a function but with a special characteristic that the program execution always starts from the 'main'. 'int' and 'void' are its return type.


1 Answers

Since the question is double-tagged as C and C++, the reasoning for C++ and C would be different:

  • C++ uses name mangling to help linker distinguish between textually identical symbols of different types, e.g. a global variable xyz and a free-standing global function xyz(int). However, the name main is never mangled.
  • C does not use mangling, so it is possible for a program to confuse linker by providing a symbol of one kind in place of a different symbol, and have the program successfully link.

That is what's going on here: the linker expects to find symbol main, and it does. It "wires" that symbol as if it were a function, because it does not know any better. The portion of runtime library that passes control to main asks linker for main, so linker gives it symbol main, letting the link phase to complete. Of course this fails at runtime, because main is not a function.

Here is another illustration of the same issue:

file x.c:

#include <stdio.h> int foo(); // <<== main() expects this int main(){     printf("%p\n", (void*)&foo);     return 0; } 

file y.c:

int foo; // <<== external definition supplies a symbol of a wrong kind 

compiling:

gcc x.c y.c 

This compiles, and it would probably run, but it's undefined behavior, because the type of the symbol promised to the compiler is different from the actual symbol supplied to the linker.

As far as the warning goes, I think it is reasonable: C lets you build libraries that have no main function, so the compiler frees up the name main for other uses if you need to define a variable main for some unknown reason.

like image 114
Sergey Kalinichenko Avatar answered Sep 22 '22 15:09

Sergey Kalinichenko