为什么调用 main 函数被认为是未定义的行为 (UB)

Sup*_*kus 3 c++ language-lawyer c++20

我担心这又是一个关于解释 ISO/IEC 14882(C++ 标准)的问题,但是:

\n

main是否从程序中调用,例如我至少main()从实现定义的行为中递归调用?main(更新:我的意思是稍后格式不正确,未定义实现,也不是 UB,请参见下文并回答)

\n

6.9.3.1 [basic.start.main] 状态

\n
\n

3 程序中不得使用 main 函数。main 的链接 (6.6) 是实现定义的......

\n
\n

共识似乎是未定义行为(UB)MSVC 的文档也指向 UB,gcc 的文档也隐含地否认实现定义的行为。它不可能是 [defns.unspecified] 未指定的行为,因为我将不解释为格式不正确。

\n

然而,尽管有这些实现,根据我的解释,不应该是 UB,而是如 4.1 [intro.compliance] 所示

\n
\n

1 可诊断规则集包含本文档中的所有语法和语义规则,但\n包含明确表示\xe2\x80\x9c 不需要诊断\xe2\x80\x9d 的规则或被描述为导致\n \xe2\x80\x9c 未定义的行为\xe2\x80\x9d。\n...\n(2.2) \xe2\x80\x94 如果程序包含违反任何可诊断规则的行为或出现\n中描述的构造当实现不支持该构造时,文档为 \xe2\x80\x9cconditionally-supported\xe2\x80\x9d,\n 符合要求的实现应发出至少一条诊断消息。

\n
\n

对我来说,推理似乎很清楚

\n
\n

太长了;博士

\n
    \n
  1. 调用 main 意味着程序包含违反 [basic.start.main] 规则的内容
  2. \n
  3. [basic.start.main] 未声明调用/使用是 UB 或不需要诊断
  4. \n
  5. \n
      \n
    1. 根据 [intro.compliance] 是“可诊断规则”的一个元素
    2. \n
    \n
  6. \n
  7. [intro.compliance] 2.2 规定违反任何可诊断规则必须发出至少一条诊断消息
  8. \n
  9. 由于 3. 和 4. main 的使用应发出至少一条诊断消息
  10. \n
  11. 由于 5.1. 不是 UB
  12. \n
  13. 由于 gcc、MSVC 或 clang 都不会发出错误或警告但可以编译,因此所有主要实现都不兼容
  14. \n
\n

当然,从7开始。我再次感觉到唐吉诃德的场景是错误的,所以如果有人能启发我关于我的错误,我将不胜感激。否则,就有标准缺陷,不是吗?

\n

Bri*_*ian 5

我认为你的分析是正确的:调用格式main不正确。

您必须传递该-pedantic标志才能使 GCC 和 Clang 保持一致。在这种情况下,Clang 说

warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会说

warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
Run Code Online (Sandbox Code Playgroud)

但他们允许拨打 至main作为分机。该标准允许这样的扩展,因为它不会改变任何符合程序的含义。

  • 我认为你的意思是“不会改变任何*格式良好的*程序的含义”。C++(截至 2017 年标准)似乎没有定义术语“符合程序”。(C 确实如此,但定义极其宽松。) (2认同)