Considérez l’extrait suivant:
void f(void); void g(…) { … return f(); … }
Est-ce que return f();
valide selon C11?
Je ne préconise pas l’utilisation de ce modèle: si cela fonctionne, il est évidemment équivalent à f(); return;
f(); return;
(où le return;
lui-même serait redondant s’il se trouvait à la fin de la fonction g()
). Je pose cette question dans le contexte de l’parsing statique des programmes C, où le code C a déjà été écrit par quelqu’un d’autre et la question est de décider s’il est valide ou non conformément à la norme.
J’interpréterais C11 6.8.6.4:1 comme signifiant qu’il est non standard et qu’il devrait être rejeté de manière statique. Est-il possible de l’interpréter différemment (j’ai trouvé ce modèle dans un code source réel et sinon de haute qualité)?
Contraintes
Une instruction de retour avec une expression ne doit pas apparaître dans une fonction dont le type de retour est void. Une instruction de retour sans expression ne doit apparaître que dans une fonction dont le type de retour est void.
Après le return
est une expression.
Syntaxe ... retourne une expression opt ;
Et standard dit que:
Une instruction de retour avec une expression ne doit pas apparaître dans une fonction dont le type de retour est void. ….
f()
est aussi une expression ici. Le compilateur devrait émettre un avertissement
[Warning] ISO C forbids 'return' with expression, in function returning void [-pedantic]
C’est clairement une violation de contrainte, en particulier eu égard à
6.3.2.2 void: la valeur (non existante) d’une expression void (une expression de type void) ne doit en aucun cas être utilisée,
Cela signifie que le void
type incomplet est une impasse qui ne peut être réutilisée à quelque fin que ce soit.
Il est clairement indiqué A return statement without an expression shall only appear in a function whose return type is void
, essayez et exécutez ceci:
void g() { return; // does not return any expression at all } void f() { return g(); } int main(void) { f(); return 0; }