【问题标题】:Why main can not be a constexpr?为什么 main 不能是 constexpr?
【发布时间】:2014-02-27 16:05:02
【问题描述】:

当您尝试像这样将 constexpr 与 main 一起使用时:

constexpr int main()

gcc 和 clang 抱怨:

错误:不能将 '::main' 声明为内联

错误:'main' 不允许被声明为 constexpr

我们来看看 constexpr 函数有哪些要求:

constexpr 函数必须满足以下要求:

  • 不能是虚拟的
  • 它的返回类型必须是 LiteralType
  • 它的每个参数都必须是字面量类型

什么是 LiteralType?

文字类型是以下任何一种

  • void(c++14 起)
  • 标量类型
  • 引用类型
  • 文字类型的数组

函数体必须包括什么?

  • 空语句
  • static_assert 声明
  • typedef 声明和别名声明不定义类或枚举
  • 使用声明
  • 使用指令
  • 正好是一个只包含文字值、constexpr 变量和函数的返回语句。

以下示例:

constexpr int main() { ; }

constexpr int main() { return 42; }

constexpr int main() {
// main defaults to return 0 
}

似乎符合所有这些要求。同样,main 是在程序开始时运行的特殊功能,然后是其他所有功能。您可以从 main 运行 constexpr 函数,并且为了使标记为 constexpr 的东西成为 constexpr,它必须在 constexpr 上下文中运行。

那么为什么main 不允许是 constexpr?

【问题讨论】:

  • 在我看来,有些人似乎痴迷于无处不在使用新的语言功能,不管这是否有意义。
  • 这将是摆脱forkexec 只执行/bin/false 所需的功能吗?
  • 在编译时永远无法知道 argc 和 argv。
  • @JohannesSchaub-litb:你实际上可以优化掉/bin/false的任何调用!
  • 问题不在于 constexpr 的定义,而在于 main 的定义

标签: c++ c++11 main language-lawyer constexpr


【解决方案1】:

不,这是不允许的 draft C++ standard 部分 3.6.1 主要功能 段落 3 说:

[...]将 main 定义为已删除或将 main 声明为内联、静态或 constexpr 的程序格式错误。[...]

main 必须是一个运行时函数,作为 Lightness says 它没有任何意义,因为您无法优化 main

【讨论】:

  • 但我的问题是为什么?
  • @ToryWebster 因为将 main 声明为 constexpr 绝对没有意义。
  • @ToryWebster 我对此表示怀疑。 没有理由这样做,所以我不明白为什么标准委员会会批准这样的规则。 main 永远不需要在 constexpr 上下文中调用。
  • @ToryWebster 如果 main 是无操作的,那么您最好根本不创建可执行文件
  • @ratchetfreak:哦? static int foo = computationThatTakesThreeWeeks(); int main() {}
【解决方案2】:

标准给出了main 的精确签名,因此允许编译器拒绝其他签名。更具体地说,它规定main 不能是constexprstatic 或其他一些东西。

如果您想知道为什么,允许编译器在 main 的开头插入代码(以执行初始化全局变量等操作),这可能使其成为非 @ 987654326@(这就是为什么程序不允许显式调用 main 的原因)。

【讨论】:

  • 但是 C++14 放宽了 constexpr 限制呢?如果编译器插入符合这些宽松限制的代码,将来 constexpr main 是否有效?
  • 通常,这些事情不会发生在 main 中,但在实现中定义调用 main 的入口点。所以这不太对。
  • @LightnessRacesinOrbit 我想我们只能猜测基本原理(除非有人引用解释它)。我的猜测是他们不想禁止编译器在 main 本身中执行此操作。
  • @user3175411:这是可能的。真的,允许它是没有意义的。您无法在编译时优化 main
  • @TimSeguine:不存在的main不可能是constexpr不是-constexpr;)
【解决方案3】:

将 main 声明为 constexpr 没有任何意义,原因有两个:1) 它是一个运行时函数。 2) 不能从其他函数或递归调用。

【讨论】:

  • +1(当我明天获得新的选票时):这也是我要说的。
  • +1 我同意@LightnessRacesinOrbit 我认为这个答案实际上没有任何问题。
  • 可能是因为循环推理:“运行时”是什么意思? “不是constexpr”似乎是一个最合理的定义。
【解决方案4】:

在我看来,原因在于将 main() 声明为 constexpr 毫无意义,标准委员会希望 C++ 编程语言有意义。

函数main()是一个处理程序入口点初始化的特殊函数——用它来计算编译时值是不明智的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 2016-12-15
    相关资源
    最近更新 更多