为什么不能推导出return类型的main?

Why can the return type of main not be deduced?

正如预期的那样,以下在 C++11 中失败,因为该语言没有 return 沼泽标准函数的类型推导:

auto main()
{
   return 0;
}

但是,C++14 会,所以我无法解释以下错误(在 GCC trunk、clang 3.8 和 Visual Studio 2015 中具有相同的结果):

error: 'main' must return 'int'

标准中是否有一段我没有看到,禁止 main 的 return 类型推导?或者两个编译器都不兼容?

(为了它的价值,我从来没有真正这样做过。int main() 为了胜利......)

来自 3.6.1 [basic.start.main]

1 A program shall contain a global function called main, which is the designated start of the program....
2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a declared return type of type int, but otherwise its type is implementation-defined...

如果标准是限制扣除,那么我认为措辞 "declared return type int" 就可以了。

正在阅读 the C++17 draft §3.6.1/2:

... and it shall have a declared return type of type int, ...

所以是的,我会说禁止使用扣除。


the last C++14 draft中几乎完全相同的措辞(与 C++17 草案相同的部分):

It shall have a declared return type of type int, ...


只是在阅读评论和其他答案后,对 可能 背后的推理进行个人反思。不允许 return 类型推导的推理是(我认为),因为编译器在看到 return 语句之前不知道 return 类型。其他类型(可隐式转换为 int)可能被 return 编辑也很常见,这会使推导的类型错误。预先声明 return 类型(通过正常的老式方式,或使用尾随 return 类型)将在声明函数时设置类型,然后可以由编译器检查并且要正确。

至于允许类型别名,它们只是一种类型的别名。所以允许例如

typedef int my_type;
my_type main() { ... }

真的和

没什么区别
int main() { ... }

来自 3.6.1/2(强调我的):

[...]it shall have a declared return type of type int, but otherwise its type is implementation-defined.

当使用 auto 时没有尾随 return 类型,函数的 声明的 return 类型 仍然是 auto,即使 推导的 return 类型 可能是其他东西。 declareddeduced 之间的区别在标准中没有明确说明,但 7.1.6.4/7 可能会说明一些问题:

When [...] a return statement occurs in a function declared with a return type that contains a placeholder type, the deduced return type [...] is determined from the type of its initializer. In the case of a return with no operand or with an operand of type void, the declared return type shall be auto and the deduced return type is void.

我的理解是:

auto main(){ return 0; }

声明的return类型仍然是auto,虽然推断return类型 将是 int。根据上面的 3.6.1/2,main 声明的 return 类型 必须 int .因此,这是错误的。

但是,尾随 return 类型被视为 声明的 return 类型 。来自 7.1.6.4/2:

If the function declarator includes a trailing-return-type (8.3.5), that trailing-return-type specifies the declared return type of the function.

$ cat a.cpp
auto main() -> int {}
$ g++ -Wall -std=c++14 a.cpp
$

所有引用在 C++14 和 C++17 中都是相同的。

正如各种评论中所讨论的那样,我确实在标准中遗漏了它,因为我认为是 C++14 FDIS 的副本实际上不是这样的东西(而是一个稍旧的草案) , "declared" 这个词被偷偷塞进了 CWG 1669 之后的相关段落。

许多答案都很好地提到了标准中的引文。但是 auto as return 类型还有另一个微妙的问题。

根据 C++ 标准 (somewhere), the return statement is not mandatory inside main(). This is explicitly mentioned in Bjarne Stroustrup's website:

In C++, main() need not contain an explicit return statement. In that case, the value returned is 0, meaning successful execution.

这意味着下面的语句是有效的:

auto main () {}

可以假设在 } 之前有一个隐式的 return 0; 语句。所以在这种情况下 auto 解释为 int。然而,从 C++14 的技术细节来看,auto 必须被 推导为 void 因为没有 return 语句!那么,“int vs void”,要考虑什么?

IMO 这是一个警告,它在逻辑意义上也阻止了 auto 作为 return 类型。