174 votes

Pourquoi pouvez vous retourner par une fonction non void sans retourner une valeur sans produire une erreur du compilateur ?

Depuis que j’ai réalisé il y a plusieurs années que cela ne produit pas une erreur par défaut (dans gcc au moins) je me suis toujours demandé pourquoi ?

Je comprends que vous pouvez émettre des indicateurs de compilateur pour produire un avertissement, mais devrait-il toujours pas une erreur ? Pourquoi est-il judicieux pour une fonction non void ne pas retourner de valeur pour être valable ?

Un exemple tel que demandé dans les commentaires :

... Compile.

151voto

C99 et C++ normes ne nécessitent pas de fonctions pour retourner une valeur. La déclaration n'a aucune valeur pour la valeur de retour de la fonction sera définie (0) seulement dans la fonction principale.

La raison en est que de vérifier si chaque chemin d'accès du code renvoie une valeur est assez difficile, et la valeur de retour peut être configuré intégré à l'assembleur ou autre difficile de méthodes.

De n2960 projet:

§ 6.6.3/2

Qui coule à la fin d'une fonction est équivalent à une déclaration sans valeur; il en résulte un comportement non défini dans la valeur de retour de la fonction.

§ 3.6.1/5

Si le contrôle atteint la fin de principal sans rencontrer un retour déclaration, l'effet est celui d' l'exécution de
return 0;

gcc vous donnera un avertissement si vous l'appelez avec -Wreturn-type d'option.

-Wreturn de type Avertir à chaque fois qu'une fonction est définie avec un retour-type de par défaut int. Aussi mettre en garde tout instruction de retour sans retourner de valeur dans une fonction dont le retour n'est pas void (tomber de la fin de la corps de la fonction est envisagé de rentrer sans valeur), et sur un retour déclaration avec une expression dans un fonction dont le retour est void.

Cet avertissement est activé par un Mur.

Juste à titre de curiosité. Regardez ce que ce code n' (1):

#include <iostream>

int foo() {
   int a = 5;
   int b = a + 1;
}

int main() { std::cout << foo() << std::endl; } // will print 6 (2)

(1) C'est l'appel de la convention et de l'architecture de la dépendance.
(2) La valeur de retour est le résultat de la dernière évaluation de l'expression, stockées dans l' eax s'inscrire.

43voto

John Kugelman Points 108754

gcc n'est pas, par défaut, vérifiez que tous les chemins de code de retour d'une valeur parce qu'en général, cela ne peut être fait. Il suppose que vous savez ce que vous faites. Considérons un exemple de l'utilisation d'énumérations:

Color getColor(Suit suit) {
    switch (suit) {
        case HEARTS: case DIAMONDS: return RED;
        case SPADES: case CLUBS:    return BLACK;
    }

    // Error, no return?
}

Vous le programmeur sait que, en l'absence d'un bug, cette méthode renvoie toujours une couleur. gcc approbations que vous savez ce que vous faites afin de ne pas vous forcer à mettre un retour à la fin de la fonction.

javac, d'autre part, essaie de vérifier que tous les chemins de code de retour d'une valeur et renvoie une erreur si il ne peut pas prouver qu'elles le sont toutes. Cette erreur est mandaté par le Java langage de spécification. Notez que parfois, c'est mal et que vous devez mettre en inutile de l'instruction return.

char getChoice() {
    int ch = read();

    if (ch == -1 || ch == 'q') {
        System.exit(0);
    }
    else {
        return (char) ch;
    }

    // Cannot reach here, but still an error.
}

C'est une différence philosophique. Le C et le C++ sont plus permissives de confiance et de langages que Java ou C# et ainsi de certaines erreurs dans les nouvelles langues sont des avertissements en C/C++ et certains avertissements sont ignorés ou désactivé par défaut.

15voto

AndreyT Points 139512

Tu veux dire, pourquoi coule au large de la fin de la valeur de retour de la fonction (c'est à dire la sortie sans un explicite return) n'est pas une erreur?

Tout d'abord, dans C, si une fonction retourne quelque chose de significatif ou n'est pas seulement critique lors de l'exécution de code utilise la valeur de retour. Peut-être que la langue ne veux pas vous forcer à retourner quoi que ce soit quand vous savez que vous n'allez pas l'utiliser de toute façon la plupart du temps.

Deuxièmement, peut-être que la spécification du langage n'a pas voulu forcer le compilateur auteurs de détecter et de vérifier tous les possibles chemins de contrôle de la présence d'un explicite return (même si ce n'est pas difficile à faire).

A noter également, que le C et le C++ diffèrent dans leurs définitions du comportement dans ce cas. En C++, il suffit d'écoulement à l'extrémité d'une valeur de retour de la fonction est toujours un comportement indéfini (quel que soit le résultat de la fonction est utilisée par le code appelant). En C, ce qui provoque un comportement indéfini seulement si le code appelant essaie d'utiliser la valeur retournée.

0voto

Martin Beckett Points 60406

C’est une erreur de compilation dans MSVC ++, Etes-vous sûr de gcc permet cela ?

Edit : la norme (semble) à dire le résultat de cela n’est pas défini.

0voto

David Thornley Points 39051

Dans quelles circonstances il ne produit pas une erreur ? S’il déclare un type de retour et ne retourne pas quelque chose, on dirait une erreur pour moi.

La seule exception que je peux penser est le fonction, qui n’a pas besoin un déclaration du tout (au moins en C++ ; Je n’ai soit des normes C très pratiques). S’il n’y a pas de retour, elle agira comme si `` est la dernière instruction.

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