Why can the return type of main not be deduced?

守給你的承諾、 提交于 2019-12-23 06:44:49

问题


As expected, the following fails in C++11 because that language does not have return type deduction for bog standard functions:

auto main()
{
   return 0;
}

However, C++14 does, so I cannot explain the following error (with equivalent outcomes in GCC trunk, clang 3.8 and Visual Studio 2015):

error: 'main' must return 'int'

Is there a passage in the standard that I'm not seeing, forbidding return type deduction for main? Or are both compilers non-compliant?

(For what it's worth, I'd never actually do this. int main() for the win…)


回答1:


Reading the C++17 draft §3.6.1/2:

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

So yes I would say it's forbidden to use deduction.


Almost the exact same wording in the last C++14 draft (same section as the C++17 draft):

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


Just a personal reflection on the possible reasoning behind this, after reading comments and other answers. The reasoning return-type deduction is not allowed is (I think) because then the return type isn't known by the compiler until it sees a return statement. It's also not uncommon that other types (that are implicitly convertible to int) might be returned which would make the deduced type wrong. Declaring the return type up-front (either by the normal old-fashioned way, or by using trailing return type) will set the type when the function is declared, and can be checked by the compiler then and there to be correct.

As for allowing type-aliases, they are just aliases of a type. So allowing e.g.

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

is really no different from

int main() { ... }



回答2:


From 3.6.1/2 (emphasis mine):

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

When auto is used without a trailing return type, the declared return type of a function is still auto, even though the deduced return type can be something else. The difference between declared and deduced isn't spelled out plainly in the standard, but 7.1.6.4/7 may shed some light:

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.

My understanding is that with this:

auto main(){ return 0; }

the declared return type would still be auto, although the deduced return type would be int. As per 3.6.1/2 above, the declared return type of main must be int. Therefore, this is ill-formed.

However, a trailing return type is considered a declared return type. From 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
$

All quotes are identical in both C++14 and C++17.




回答3:


From 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...

If the standard were to restrict deduction, then I think the verbiage "declared return type int" would be it.




回答4:


Many answers have nicely mention the quotes from the standard. But there is another subtle problem with auto as return type.

According to C++ standard (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.

Which means below statement is valid:

auto main () {}

One can assume an implicit return 0; statement just before }. So in such case auto is interpreted as int. However, from technicality of C++14, the auto must be deduced to void because of no return statement! So, "int vs void", what to consider?

IMO this is the caveat, which prevents auto as a return type in a logical sense as well.




回答5:


As discussed in various comments, I was indeed missing it in the standard, because what I thought was a copy of the C++14 FDIS was in fact no such thing (but, instead, a marginally older draft), and the word "declared" was snuck into the relevant passage after CWG 1669.



来源:https://stackoverflow.com/questions/39106798/why-can-the-return-type-of-main-not-be-deduced

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!