正如预期的那样,C ++ 11中的以下内容失败,因为该语言没有针对沼泽标准函数的返回类型推导:
auto main()
{
return 0;
}
但是,C ++ 14确实如此,所以我无法解释以下错误(在GCC trunk,clang 3.8和Visual Studio 2015中具有相同的结果):
error: 'main' must return 'int'
我没有看到标准中的段落,禁止main
的退货类型扣除?或者两个编译器都不兼容?
(对于它的价值,我从来没有真正这样做。int main()
获胜......)
答案 0 :(得分:23)
阅读the C++17 draft§3.6.1/ 2:
...它应具有类型为
int
的声明的返回类型,...
所以是的我会说它被禁止使用扣除。
the last C++14 draft中几乎完全相同的措辞(与C ++ 17草案相同):
它的声明返回类型为
int
,...
在阅读评论和其他答案之后,只是对这背后的可能的推理的个人反思。 (我认为)不允许推理返回类型推导,因为编译器在查看return
语句之前不知道返回类型。其他类型(可隐式转换为int
)可能会被返回,这会导致推断类型错误。预先声明返回类型(通过正常的老式方式,或使用尾随返回类型)将在声明函数时设置类型,然后由编译器检查然后是正确的。
至于允许类型别名,它们只是一种类型的别名。所以允许例如
typedef int my_type;
my_type main() { ... }
与
无异int main() { ... }
答案 1 :(得分:17)
从3.6.1 / 2(强调我的):
[...]它应具有类型为
int
的声明的返回类型,但其类型是实现定义的。
当使用auto
而没有尾随返回类型时,函数的声明的返回类型仍然是auto
,即使推断的返回类型可以是其他东西。 声明和推导之间的区别在标准中没有明确说明,但7.1.6.4/7可能会有所启发:
当使用包含占位符类型的返回类型声明的函数中发生
return
语句时,推导出的返回类型[...]由其初始值设定项的类型确定。如果return
没有操作数或操作数类型为void
,则声明的返回类型应为auto
,推导的返回类型为void
。
我的理解是:
auto main(){ return 0; }
声明的返回类型仍然是auto
,尽管推断的返回类型将是int
。根据上面的3.6.1 / 2,main
的声明的返回类型必须为int
。因此,这是不正确的。
但是,尾随返回类型被视为声明的返回类型。从7.1.6.4/2开始:
如果函数声明符包含 trailing-return-type (8.3.5),则 trailing-return-type 指定函数的声明返回类型。 / p>
$ cat a.cpp
auto main() -> int {}
$ g++ -Wall -std=c++14 a.cpp
$
C ++ 14和C ++ 17中的所有引号都相同。
答案 2 :(得分:8)
来自3.6.1 [basic.start.main]
1程序应包含一个名为main的全局函数,即 指定的程序开始....
2实施不得 预定义主要功能。此功能不应过载。它 应该具有int类型的声明返回类型,否则它的类型 是实现定义的......
如果标准是限制扣除,那么我认为“声明返回类型为int”的措辞就是它。
答案 3 :(得分:3)
正如在各种评论中所讨论的那样,我确实在标准中忽略了它,因为我认为是C ++ 14 FDIS的副本实际上没有这样的东西(但是,相反,是一个稍微更旧的草案),以及声明"宣布"在CWG 1669之后偷偷溜进了相关的段落。