32 votes

Pourquoi le type de retour de main ne peut-il pas être déduit?

Comme prévu, la suite ne parvient pas en C++11 parce que la langue n'a pas de type de retour de la déduction pour la tourbière de fonctions standard:

auto main()
{
   return 0;
}

Cependant, C++14 fait, donc je ne peut pas expliquer l'erreur suivante (avec des résultats équivalents dans GCC tronc, clang 3.8 et Visual Studio 2015):

error: 'main' must return 'int'

Est-il un passage dans la norme que je ne suis pas voyant, interdisant le type de retour de la déduction pour main? Ou sont les deux compilateurs non-conforme?

(Pour ce que ça vaut, je n'avais jamais fait cela. int main() pour la victoire...)

23voto

Joachim Pileborg Points 121221

La lecture du C++17 projet §3.6.1/2:

... et il doit avoir une déclaration de type de retour de type int, ...

Donc, oui, je dirais qu'il est interdit d'utiliser la déduction.


Presque exactement la même formulation dans le dernier C++14 projet (même section que le C++17 le projet):

Il doit avoir une déclaration de type de retour de type int, ...


Juste une réflexion personnelle sur la possible raisonnement derrière cela, après la lecture des commentaires et d'autres réponses. Le raisonnement de retour de déduction n'est pas autorisé est (je pense) parce que le type de retour n'est pas connue par le compilateur jusqu'à ce qu'il voit un return déclaration. Il n'est également pas rare que d'autres types (qui sont implicitement convertible int) peuvent être retournées qui ferait de la déduit le type de mal. Déclarer le type de retour à l'avant (soit par la normale à l'ancienne manière, ou en utilisant de fuite type de retour) permettra de définir le type lorsque la fonction est déclarée, et peut être vérifié par le compilateur, alors et là pour être correct.

Comme pour permettant de type alias, ils sont tout simplement des alias d'un type. Afin de permettre par exemple

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

c'est vraiment pas différent de

int main() { ... }

17voto

isanae Points 973

À partir 3.6.1/2 (l'emphase est mienne):

[...]il doit avoir un type de retour déclaré de type int, mais sinon, il est de type définies par l'implémentation.

Lors de l' auto est utilisé sans une fuite de type de retour, l' a déclaré le type de retour d'une fonction est toujours auto, même si le déduire le type de retour peut être autre chose. La différence entre déclarée et déduit n'est pas énoncé clairement dans la norme, mais 7.1.6.4/7 peut jeter de la lumière:

Quand [...] un return déclaration se produit dans une fonction déclarée avec un type de retour qui contient un espace réservé à un type, le déduit le type de retour [...] est déterminée à partir du type de son initialiseur. Dans le cas d'un return sans opérande ou avec un opérande de type void, la déclaration de type de retour doit être auto et le déduit le type de retour est - void.

Ma compréhension est que, avec ceci:

auto main(){ return 0; }

le type de retour déclaré seraient encore en auto, bien que la déduit le type de retour serait int. Comme par 3.6.1/2 ci-dessus, a déclaré le type de retour d' main doit être int. Donc, c'est mal formé.

Cependant, une fuite en type de retour est considéré comme un type de retour déclaré. De 7.1.6.4/2:

Si la fonction de demande de déclaration comprend une fuite-retour-type (8.3.5), que la fuite-retour de type spécifie la déclaration de type de retour de la fonction.

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

Toutes les citations sont identiques dans les deux C++14 et C++17.

8voto

AndyG Points 3298

À partir 3.6.1 [de base.commencer.principal]

1 Un programme doit contenir une fonction globale, appelée main, qui est la désigné début du programme....
2 Une mise en œuvre ne doit pas prédéfinir la fonction principale. Cette fonction ne doit pas être surchargé. Il doit avoir une déclaration de type de retour de type int, mais sinon, son type la mise en œuvre est définie par...

Si le standard était de limiter la déduction, alors je pense que le verbiage ", a déclaré le retour de type int" serait-il.

4voto

iammilind Points 29275

De nombreuses réponses ont bien mentionner les citations de la norme. Mais il y a un autre problème subtil auto comme type de retour.

Selon la norme C++ (quelque part), l' return déclaration n'est pas obligatoire à l'intérieur d' main(). Cela est explicitement mentionné dans Bjarne Stroustrup du site web:

En C++, main() n'a pas besoin d'indiquer explicitement return déclaration. Dans ce cas, la valeur retournée est - 0, signifiant la réussite de l'exécution.

Ce qui signifie déclaration ci-dessous est valide:

auto main () {}

On peut supposer implicitement return 0; déclaration juste avant }. Dans de tels cas auto est interprété en int. Cependant, à partir de la technicité de C++14, l' auto doit être déduites void à cause de pas d'instruction de retour! Ainsi, "int vs void", ce qui compte?

IMO c'est la mise en garde, ce qui empêche auto un type de retour dans une logique de bon sens ainsi.

3voto

Comme nous l'avons mentionné dans divers commentaires, je l'ai effectivement manqué dans la norme, parce que ce que je croyais être une copie du FDIS c'était en fait une telle chose (mais, au lieu de cela, un projet légèrement plus ancien), et le mot «déclaré» a été glissé dans le passage pertinent après CWG 1669.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X