43 votes

Peut-on supprimer une fonction renvoyant un type incomplet en C++ ?

Dans l'exemple suivant, la fonction f() renvoyant le type incomplet A est marquée comme supprimée :

struct A;
A f() = delete;

Cela est accepté par GCC, mais pas par Clang, qui se plaint :

erreur : type de résultat incomplet 'A' dans la définition de la fonction

Démo : https://gcc.godbolt.org/z/937PEz1h3

Quel compilateur a raison ici selon la norme ?

0 votes

0 votes

Merci pour la référence. C'est une question très vaste, mais on peut trouver une réponse ici.

32voto

StoryTeller Points 6139

Clang a tort.

[dcl.fct.def.general]

2 Le type d'un paramètre ou le type de retour pour une définition de fonction ne doit pas être un type de classe (éventuellement avec des cv-qualifications) qui est incomplet ou abstrait dans le corps de la fonction à moins que la fonction soit supprimée ([dcl.fct.def.delete]).

Je pense que c'est assez clair. Une définition supprimée permet un type de classe incomplet. Ce n'est pas comme si la fonction pouvait réellement être appelée dans un programme bien formé, ou que le corps utilise vraiment le type incomplet de quelque manière que ce soit. La fonction est un espace réservé pour indiquer un résultat invalide à la résolution de surcharge.

Admettons, les types de paramètres sont plus intéressants dans le cas de la résolution réelle de la surcharge (et le type de retour peut être n'importe quoi), mais il n'y a aucune raison de restreindre le type de retour à être complet ici non plus.

24voto

binaryBaBa Points 688

Au début, au paragraphe 9.3.4.6 [dcl.fct], le paragraphe 9 exigeait que

Le type d'un paramètre ou le type de retour pour une définition de fonction ne doit pas être un type de classe incomplète (éventuellement qualifié cv) sauf si la définition de la fonction est imbriquée dans la spécification des membres de cette classe (y compris les définitions dans les classes imbriquées définies à l'intérieur de la classe).

Un rapport de défaut a été soulevé, et une résolution ultérieure proposée et appliquée rétroactivement (mes soulignements):

Les types ne doivent pas être définis dans les types de retour ou de paramètre. Le type d'un paramètre ou le type de retour pour une définition de fonction ne doit pas être un type de classe incomplète (éventuellement qualifié cv) à moins que la fonction ne soit supprimée (9.5.3 [dcl.fct.def.delete]) ou que la définition soit imbriquée dans la spécification des membres de cette classe (y compris les définitions dans les classes imbriquées définies à l'intérieur de la classe).

Par conséquent, Clang a tort.

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