为什么调用主函数应该是未定义的行为 (UB)
Why is calling the main function supposedly undefined behavior (UB)
我担心这又是一个关于解释 ISO/IEC 14882(C++ 标准)的问题但是:
正在从程序中调用 main
,例如我从 main
递归调用 main()
至少不是实现定义的行为? (更新:我的意思是稍后格式错误,未定义实现,也不是 UB,请参见下文并回答)
6.9.3.1 [basic.start.main] 状态
3 The function main shall not be used within a program. The linkage (6.6) of main is implementation-defined...
consensus seems to be undefined behavior (UB). The documentation of MSVC also points towards UB, the one of gcc 也隐含地否定了实现定义的行为。它不能是 [defns.unspecified] 未指定的行为,因为我会将 不应 解释为格式错误。
然而,尽管有这些实现,但根据我的解释,不应该是 UB,而是 4.1 [intro.compliance] 声明
1 The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those
rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in
“undefined behavior”.
...
(2.2) — If a program contains a violation of any diagnosable rule or an occurrence of a construct described in
this document as “conditionally-supported” when the implementation does not support that construct,
a conforming implementation shall issue at least one diagnostic message.
对我来说,推理似乎很清楚
tl;博士
- 调用 main 意味着程序违反了 [basic.start.main]
的规则
- [basic.start.main] 未说明 calling/use 是 UB 或不需要诊断
-
- 是根据 [intro.compliance]
的“可诊断规则”的一个元素
- [intro.compliance] 2.2 声明违反任何可诊断规则必须至少发出一条诊断消息
- 从 3. 和 4. 开始,main 的使用应至少发出一条诊断消息
- 因为 5.1. 不是 UB
- 由于 gcc、MSVC 或 clang 都不会发出错误或警告但会编译,因此所有主要实现都不兼容
当然是从7开始的。我又一次在唐吉诃德的场景中感觉自己错了,所以如果有人能告诉我我的错误,我将不胜感激。否则,有标准缺陷,不是吗?
我认为您的分析是正确的:对 main
的调用格式错误。
您必须传递 -pedantic
标志以使 GCC 和 Clang 符合。在那种情况下,Clang 说
warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]
GCC 说
warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
但是他们允许呼叫 main
作为分机。该标准允许这样的扩展,因为它不会改变任何符合标准的程序的含义。
我担心这又是一个关于解释 ISO/IEC 14882(C++ 标准)的问题但是:
正在从程序中调用 main
,例如我从 main
递归调用 main()
至少不是实现定义的行为? (更新:我的意思是稍后格式错误,未定义实现,也不是 UB,请参见下文并回答)
6.9.3.1 [basic.start.main] 状态
3 The function main shall not be used within a program. The linkage (6.6) of main is implementation-defined...
consensus seems to be undefined behavior (UB). The documentation of MSVC also points towards UB, the one of gcc 也隐含地否定了实现定义的行为。它不能是 [defns.unspecified] 未指定的行为,因为我会将 不应 解释为格式错误。
然而,尽管有这些实现,但根据我的解释,不应该是 UB,而是 4.1 [intro.compliance] 声明
1 The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”. ... (2.2) — If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
对我来说,推理似乎很清楚
tl;博士
- 调用 main 意味着程序违反了 [basic.start.main] 的规则
- [basic.start.main] 未说明 calling/use 是 UB 或不需要诊断
-
- 是根据 [intro.compliance] 的“可诊断规则”的一个元素
- [intro.compliance] 2.2 声明违反任何可诊断规则必须至少发出一条诊断消息
- 从 3. 和 4. 开始,main 的使用应至少发出一条诊断消息
- 因为 5.1. 不是 UB
- 由于 gcc、MSVC 或 clang 都不会发出错误或警告但会编译,因此所有主要实现都不兼容
当然是从7开始的。我又一次在唐吉诃德的场景中感觉自己错了,所以如果有人能告诉我我的错误,我将不胜感激。否则,有标准缺陷,不是吗?
我认为您的分析是正确的:对 main
的调用格式错误。
您必须传递 -pedantic
标志以使 GCC 和 Clang 符合。在那种情况下,Clang 说
warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]
GCC 说
warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
但是他们允许呼叫 main
作为分机。该标准允许这样的扩展,因为它不会改变任何符合标准的程序的含义。