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

2022-05-16 00:00:00 language-lawyer c++ c++20

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

从程序调用main,例如从main递归调用main()至少不是实现定义的行为吗?(更新:我暗示稍后未定义格式错误的未实现,也未定义UB,请参阅下文并回答)

6.9.3.1[basic.start.main]状态

3函数Main不得在程序内使用。Main的链接(6.6)由实现定义...

consensus似乎是未定义的行为(UB)。documentation of MSVC还指向UB,one of gcc还隐式拒绝实现定义的行为。它不能是未指定的行为,因为我会将不应解释为格式错误。

然而,尽管有这些实现,我的解释是不应该是UB,而是正如4.1[Intro.Compliance]所述

1可诊断规则集由本文档中的所有语法和语义规则组成,但 包含"不需要诊断"的显式表示法或被描述为导致 "未定义的行为"。 ..。 (2.2)-如果程序包含对任何可诊断规则的违反或出现中描述的构造 当实现不支持该构造时,该文档被认为是"有条件支持的", 一致性实现应至少发出一条诊断消息。

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


tl;dr
  1. 调用Main表示程序违反了[basic.start.main]
  2. 规则
  3. [basic.start.main]未声明调用/使用为UB或不需要诊断
    1. 是可诊断规则的元素,根据[Intro.Compliance]
  4. [Intro.Compliance]2.2规定必须至少向违反任何可诊断规则的行为发出一条诊断消息
  5. 自3.和4.使用Main后,应至少发出一条诊断消息
  6. 从5.1开始不是UB
  7. 由于GCC、msvc和clang都不发出错误或警告,而是编译,所以所有主要实现都不符合

当然是从第7天起。我再次感觉到唐吉柯德的场景是错误的,所以如果有人能告诉我我的错误,我将不胜感激。否则就有标准缺陷,不是吗?


解决方案

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

您必须通过-pedantic旗帜才能使GCC和郎朗保持一致。在这种情况下,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作为扩展。该标准允许这样的扩展,因为它不会更改任何符合标准的程序的含义。

相关文章