Is main() really start of a C++ program?

2019-01-02 17:00发布

The section $3.6.1/1 from the C++ Standard reads,

A program shall contain a global function called main, which is the designated start of the program.

Now consider this code,

int square(int i) { return i*i; }
int user_main()
{ 
    for ( int i = 0 ; i < 10 ; ++i )
           std::cout << square(i) << endl;
    return 0;
}
int main_ret= user_main();
int main() 
{
        return main_ret;
}

This sample code does what I intend it to do, i.e printing the square of integers from 0 to 9, before entering into the main() function which is supposed to be the "start" of the program.

I also compiled it with -pedantic option, GCC 4.5.0. It gives no error, not even warning!

So my question is,

Is this code really Standard conformant?

If it's standard conformant, then does it not invalidate what the Standard says? main() is not start of this program! user_main() executed before the main().

I understand that to initialize the global variable main_ret, the use_main() executes first but that is a different thing altogether; the point is that, it does invalidate the quoted statement $3.6.1/1 from the Standard, as main() is NOT the start of the program; it is in fact the end of this program!


EDIT:

How do you define the word 'start'?

It boils down to the definition of the phrase "start of the program". So how exactly do you define it?

11条回答
刘海飞了
2楼-- · 2019-01-02 17:43

Your "program" simply returns a value from a global variable. Everything else is initialization code. Thus, the standard holds - you just have a very trivial program and more complex initialization.

查看更多
听够珍惜
3楼-- · 2019-01-02 17:46

The compiler often has to add code before main() to be standard compliant. Because the standard specifies that initalization of globals/statics must be done before the program is executed. And as mentioned, the same goes for constructors of objects placed at file scope (globals).

Thus the original question is relevant to C as well, because in a C program you would still have the globals/static initialization to do before the program can be started.

The standards assume that these variables are initialized through "magic", because they don't say how they should be set before program initialization. I think they considered that as something outside the scope of a programming language standard.

Edit: See for example ISO 9899:1999 5.1.2:

All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified.

The theory behind how this "magic" was to be done goes way back to C's birth, when it was a programming language intended to be used only for the UNIX OS, on RAM-based computers. In theory, the program would be able to load all pre-initialized data from the executable file into RAM, at the same time as the program itself was uploaded to RAM.

Since then, computers and OS have evolved, and C is used in a far wider area than originally anticipated. A modern PC OS has virtual addresses etc, and all embedded systems execute code from ROM, not RAM. So there are many situations where the RAM can't be set "automagically".

Also, the standard is too abstract to know anything about stacks and process memory etc. These things must be done too, before the program is started.

Therefore, pretty much every C/C++ program has some init/"copy-down" code that is executed before main is called, in order to conform with the initialization rules of the standards.

As an example, embedded systems typically have an option called "non-ISO compliant startup" where the whole initialization phase is skipped for performance reasons, and then the code actually starts directly from main. But such systems don't conform to the standards, as you can't rely on the init values of global/static variables.

查看更多
旧时光的记忆
4楼-- · 2019-01-02 17:46

main is called after initializing all the global variables.

What the standard does not specify is the order of initialization of all the global variables of all the modules and statically linked libraries.

查看更多
查无此人
5楼-- · 2019-01-02 17:49

Seems like an English semantics quibble. The OP refers to his block of code first as "code" and later as the "program." The user writes the code, and then the compiler writes the program.

查看更多
长期被迫恋爱
6楼-- · 2019-01-02 17:50

main() is a user function called by the C runtime library.

see also: Avoiding the main (entry point) in a C program

查看更多
登录 后发表回答