2010-08-04 15 views
19

Je viens d'avoir un comportement étrange d'une version de g ++ pour Windows que j'ai eu avec Strawberry Perl. Cela m'a permis d'omettre une déclaration de retour.Omettre l'instruction return en C++

J'ai une fonction membre qui retourne une structure composée de deux pointeurs, appelé boundTag:

struct boundTag Box::getBound(int side) { 
    struct boundTag retBoundTag; 
    retBoundTag.box = this; 
    switch (side) 
    { 
     // set retBoundTag.bound based on value of "side" 
    } 
} 

Cette fonction m'a donné une mauvaise sortie, et j'ai découvert qu'il avait pas de déclaration de retour. J'avais l'intention de retourner retBoundTag, mais j'ai oublié d'écrire réellement la déclaration de retour. Une fois que j'ai ajouté return retBoundTag; tout allait bien. Mais j'ai testé cette fonction et j'ai obtenu la sortie boundTag correcte. Même maintenant, quand je supprime l'instruction return, g ++ la compile sans avertissement. WTF? Est-il deviner de retourner retBoundTag?

+5

Vous devriez compiler en utilisant '-Wall'. Les instructions de retour manquantes sont interceptées par '-Wreturn-type'. – jweyrich

+0

J'ai tendance à transformer l'avertissement concernant un retour manquant en erreur avec: '-Werror = return-type'. M'a sauvé beaucoup de temps. –

Répondre

16

Omettre la déclaration return dans une fonction non-void [Sauf main()] et en utilisant la valeur retournée dans votre code appelle Undefined Behaviour.

ISO C++ - 98 [Section 6.6.3/2]

Une déclaration de retour avec une expression peut être utilisé que dans les fonctions qui retournent une valeur; la valeur de l'expression est renvoyée à l'appelant de la fonction. Si nécessaire, l'expression est implicitement convertie en le type de retour de la fonction dans laquelle il apparaît . Une déclaration de retour peut impliquer la construction et la copie de un objet temporaire (class.temporary). L'écoulement de la fin d'une fonction équivaut à un retour sans valeur; il en résulte un comportement non défini dans une fonction de retour de valeur.

Par exemple

int func() 
{ 
    int a=10; 
    //do something with 'a' 
    //oops no return statement 
} 


int main() 
{ 
    int p=func(); 
    //using p is dangerous now 
    //return statement is optional here 
} 

En général g ++ donne un warning: control reaches end of non-void function. Essayez de compiler avec l'option -Wall. C et C++ ne nécessitent pas d'avoir une instruction return

+7

L'omission de l'instruction return est correcte. L'exécution atteignant la fin d'une fonction sans rencontrer d'instruction renvoie un comportement indéfini. Vous pouvez revenir avant d'atteindre la fin de la fonction, ou partir en lançant une exception, ou simplement ne jamais partir du tout, et tout serait bien défini. –

+0

pourquoi utiliser 'p' est dangereux? – ajay

+2

@ajay: C'est parce qu'il ne contient aucune valeur spécifiée. –

12

Il n'est peut-être pas nécessaire d'en avoir un, car la fonction entre dans une boucle infinie ou parce qu'elle déclenche une exception.

Prasoon déjà cité la partie pertinente de la norme:

[Section 6.6.3/2]

Une déclaration de retour avec une expression peut être utilisée que dans les fonctions qui retournent une valeur; la valeur de l'expression est renvoyée à l'appelant de la fonction. Si nécessaire, l'expression est implicitement convertie en le type de retour de la fonction dans laquelle elle apparaît. Une déclaration de retour peut impliquer la construction et la copie d'un objet temporaire (class.temporary). S'écouler à la fin d'une fonction équivaut à un retour sans valeur; cela entraîne un comportement indéfini dans une fonction de renvoi de valeur.

Ce que cela signifie est que ne pas avoir une déclaration de retour est ok. Mais atteignant la fin de la fonction sans retour est undefined comportement.

Le compilateur ne peut pas toujours détecter ces cas, il n'est donc pas nécessaire d'être une erreur de compilation (il faudrait résoudre le problème d'arrêt pour déterminer si atteint réellement la fin de la fonction). Il est simplement non défini ce qui devrait se passer si cela se produit. Cela peut sembler fonctionner (parce que la fonction d'appel se contentera de regarder quelle que soit la valeur de la poubelle à l'endroit où la valeur de retour est censée être), elle pourrait tomber en panne ou faire sortir les démons de votre nez.

+3

Merci d'expliquer pourquoi ce n'est pas une erreur de compilation de ne pas avoir une instruction return explicite dans non-void les fonctions :) – ajay

2

Même si le compilateur aC ne peut pas toujours détecter quand une fonction ne peut pas exécuter une instruction de retour, il habituellement peut. Pour le bon côté, au moins g ++ le rend facile à détecter avec l'option de compilateur de ligne de commande "-Wreturn-type". Vous avez juste besoin de vous souvenir de l'activer. (Il est également activé si vous utilisez "-Wall".)