main() 真的是 C++ 程序的开始吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4783404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:28:30  来源:igfitidea点击:

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

c++standards-compliancemainentry-point

提问by Nawaz

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

C++ 标准中的 $3.6.1/1 部分读取,

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

程序应包含一个名为main的全局函数,它是程序的指定开始

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, beforeentering into the main()function which is supposed to be the "start" of the program.

这个示例代码完成了我想要它做的事情,即进入main()应该是程序“开始”的函数之前打印从 0 到 9 的整数的平方。

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

我还用-pedantic选项 GCC 4.5.0编译了它。它没有给出错误,甚至没有警告!

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().

如果它符合标准,那么它不会使标准所说的无效吗?main()不是这个程序的开始!user_main()之前执行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 doesinvalidate the quoted statement $3.6.1/1 from the Standard, as main()is NOT the startof the program; it is in fact the endof thisprogram!

我知道要初始化全局变量main_retuse_main()首先执行,但这完全是另一回事;关键是,它确实使标准中引用的语句 $3.6.1/1 无效,因为main()它不是程序的开始;这实际上是这个程序的结尾



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?

它归结为短语“程序开始”的定义。那么你如何定义它呢?

采纳答案by Edwin Buck

No, C++ does a lot of things to "set the environment" prior to the call of main; however, main is the official start of the "user specified" part of the C++ program.

不,C++在调用main之前做了很多事情来“设置环境”;然而,main 是 C++ 程序“用户指定”部分的正式开始。

Some of the environment setup is not controllable (like the initial code to set up std::cout; however, some of the environment is controllable like static global blocks (for initializing static global variables). Note that since you don't have full control prior to main, you don't have full control on the order in which the static blocks get initialized.

一些环境设置是不可控的(比如设置 std::cout 的初始代码;但是,一些环境是可控的,比如静态全局块(用于初始化静态全局变量)。请注意,由于您没有完整的在 main 之前进行控制,您无法完全控制静态块的初始化顺序。

After main, your code is conceptually "fully in control" of the program, in the sense that you can both specify the instructions to be performed and the order in which to perform them. Multi-threading can rearrange code execution order; but, you're still in control with C++ because you specified to have sections of code execute (possibly) out-of-order.

在 main 之后,您的代码在概念上“完全控制”了程序,从某种意义上说,您既可以指定要执行的指令,也可以指定执行它们的顺序。多线程可以重新排列代码执行顺序;但是,您仍然可以使用 C++ 进行控制,因为您指定让代码段(可能)乱序执行。

回答by Adam Davis

You are reading the sentence incorrectly.

你读错了句子。

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

程序应包含一个名为 main 的全局函数,它是程序的指定开始。

The standard is DEFINING the word "start" for the purposes of the remainder of the standard. It doesn't say that no code executes before mainis called. It says that the start of the program is considered to be at the function main.

该标准为标准的其余部分定义了“开始”一词。它并不是说在main调用之前没有执行任何代码。它说程序的开始被认为是在函数处main

Your program is compliant. Your program hasn't "started" until main is started. The constructor is called before your program "starts" according to the definition of "start" in the standard, but that hardly matters. A LOT of code is executed before mainis evercalled in every program, not just this example.

你的程序是合规的。在 main 启动之前,您的程序还没有“启动”。根据标准中“开始”的定义,在程序“开始”之前调用构造函数,但这并不重要。代码很多之前执行的main曾经被称为在每一个程序,不只是这个例子。

For the purposes of discussion, your constructor code is executed prior to the 'start' of the program, and that is fully compliant with the standard.

出于讨论的目的,您的构造函数代码在程序“开始”之前执行,并且完全符合标准。

回答by CashCow

Your program will not link and thus not run unless there is a main. However main() does not cause the start of the execution of the program because objects at file level have constructors that run beforehand and it would be possible to write an entire program that runs its lifetime before main() is reached and let main itself have an empty body.

您的程序不会链接,因此不会运行,除非有主程序。但是 main() 不会导致程序开始执行,因为文件级别的对象具有预先运行的构造函数,并且可以编写一个在到达 main() 之前运行其生命周期的整个程序,并让 main 本身具有一个空的身体。

In reality to enforce this you would have to have one object that is constructed prior to main and its constructor to invoke all the flow of the program.

实际上,要强制执行此操作,您必须先构造一个对象,该对象先于 main 及其构造函数来调用程序的所有流程。

Look at this:

看这个:

class Foo
{
public:
   Foo();

 // other stuff
};

Foo foo;

int main()
{
}

The flow of your program would effectively stem from Foo::Foo()

您的程序流将有效地源于 Foo::Foo()

回答by Remo.D

You tagged the question as "C" too, then, speaking strictly about C, your initialization should fail as per section 6.7.8 "Initialization" of the ISO C99 standard.

您也将问题标记为“C”,然后,严格来说 C,您的初始化应该按照 ISO C99 标准的第 6.7.8 节“初始化”失败。

The most relevant in this case seems to be constraint #4 which says:

在这种情况下,最相关的似乎是约束 #4,它说:

All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字。

So, the answer to your question is that the code is not compliant to the C standard.

因此,您的问题的答案是该代码不符合 C 标准。

You would probably want to remove the "C" tag if you were only interested to the C++ standard.

如果您只对 C++ 标准感兴趣,您可能想要删除“C”标签。

回答by aschepler

Section 3.6 as a whole is very clear about the interaction of mainand dynamic initializations. The "designated start of the program" is not used anywhere else and is just descriptive of the general intent of main(). It doesn't make any sense to interpret that one phrase in a normative way that contradicts the more detailed and clear requirements in the Standard.

整个 3.6 节对main动态初始化和动态初始化的交互非常清楚。“程序的指定开始”未在其他任何地方使用,仅用于描述main(). 以与标准中更详细和明确的要求相矛盾的规范方式解释该短语是没有任何意义的。

回答by Lundin

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

编译器通常必须在 main() 之前添加代码以符合标准。因为标准规定必须在执行程序之前完成 globals/statics 的初始化。如前所述,放置在文件范围(全局)中的对象的构造函数也是如此。

Thus the original question isrelevant 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.

因此,最初的问题与 C 相关,因为在 C 程序中,您仍然需要在程序启动之前进行全局/静态初始化。

The standards assume that these variables are initialized through "magic", because they don't say howthey 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:

编辑:例如参见 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.

如何实现这种“魔法”背后的理论可以追溯到 C 的诞生,当时它是一种编程语言,旨在仅用于基于 RAM 的计算机上的 UNIX 操作系统。理论上,该程序将能够将可执行文件中的所有预初始化数据加载到 RAM 中,同时将程序本身上传到 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".

从那时起,计算机和操作系统不断发展,C 的使用领域比最初预期的要广泛得多。现代 PC 操作系统具有虚拟地址等,并且所有嵌入式系统都从 ROM 而非 RAM 执行代码。所以在很多情况下无法“自动”设置 RAM。

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.

因此,几乎每个 C/C++ 程序都有一些在调用 main 之前执行的 init/“copy-down”代码,以符合标准的初始化规则。

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.

例如,嵌入式系统通常有一个称为“非 ISO 兼容启动”的选项,其中出于性能原因跳过整个初始化阶段,然后代码实际上直接从 main 开始。但是这样的系统不符合标准,因为您不能依赖全局/静态变量的初始值。

回答by Zac Howland

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.

您的“程序”只是从全局变量返回一个值。其他一切都是初始化代码。因此,标准成立 - 您只有一个非常简单的程序和更复杂的初始化。

回答by sylvanaar

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

main() 是由 C 运行时库调用的用户函数。

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

另请参阅:避免 C 程序中的主要(入口点)

回答by dSerk

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.

似乎是英语语义上的狡辩。OP首先将他的代码块称为“代码”,然后称为“程序”。用户编写代码,然后编译器编写程序。

回答by vz0

main is called after initializing all the global variables.

main 在初始化所有全局变量后被调用。

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

标准没有规定的是所有模块和静态链接库的所有全局变量的初始化顺序。