Question

De nombreuses fonctions standard C et POSIX retour -1 d'erreur et 0 en cas de succès, par exemple truncate , fflush , msync , etc.

int ret = truncate("/some/file", 42);

est-il une meilleure pratique pour vérifier le succès avec ret != -1 ou ret == 0, et pourquoi?

Pensées Mes

Il est mon expérience la plupart des gens vérifient le cas d'erreur (ret != -1), car il n'y a généralement qu'un seul (considérer des fonctions que NULL de retour ou EOF en cas d'erreur). Cependant, avec le recul, on a pu voir ces fonctions pourraient bénéficier de retourner errno directement (où 0 est considéré comme pas d'erreur).

Il y a aussi l'inquiétude qu'une fonction retourne autre chose que 0 ou -1, ou que les valeurs de retour supplémentaires sont ajoutées ultérieurement. Dans ces scénarios, il est logique de test pour le « plus serré » plage de valeurs indiquant le succès (ret == 0).

Update0

Il est une hypothèse à moi que les gens sont conscients que EOF est généralement définie comme -1.

Était-ce utile?

La solution

À mon avis, cela dépend vraiment de ce que vous devez faire et la gamme des valeurs de retour.

Prendre un appel avec une valeur de succès et de nombreuses valeurs d'échec. Il est généralement plus facile à == ou != contre la valeur de retour de succès que contre les valeurs vérification de défaillance. Dans ce cas, vous tester contre != success si vous devez, par exemple, connectez-vous et retour ou jeter en cas d'échec.

Dans un appel à l'un et l'autre, le comportement souhaité est plus important, donc je vous suggère de choisir le plus facile à lire. Si vos codes doit réagir et éventuellement revenir en cas d'échec, puis vérifiez == failure au lieu de != success. Le premier est plus facile à lire, car il faut une étape de la pensée et la constante d'échec peut être utilement nommé.

Vous pouvez également envisager ce qui est plus probable et la poignée que la première, ou qui est numériquement plus ou moins.

Dans votre cas, avec deux fonctions partageant un code de réussite et avec des codes de défaillance, il tombe à ce qui semble le plus facile à lire. Je suis d'accord que le dépistage des == 0 dans les deux cas semble mieux, mais cela dépend vraiment de combien le code vient entre les appels. Si vous avez quelques dizaines de lignes, il n'y aurait pas beaucoup de différence dans la lisibilité. S'il est très proche, vous pourriez même être en mesure ou les résultats ensemble et Epargnez-vous quelques étapes.

Autres conseils

Cela dépend si la fonction est une fonction de la bibliothèque standard C ou une fonction POSIX. fonctions C ne sont pas une norme uniforme pour les codes de retour donc j'utiliser tout essai fait le plus de sens au cas par cas.

Posix, d'autre part, est plus cohérente. Presque toutes les fonctions sont définies pour POSIX retourner -1 avec un code d'erreur plus spécifique disponible dans errno. Certaines fonctions renvoient simplement 0 pour le succès, tandis que d'autres ont une multitude de valeurs de succès. Par exemple, les descripteurs de fichiers retourne open(), read() renvoie le nombre d'octets lus, etc.

Pour I cohérence comme de toujours utiliser le même test lors de l'appel des fonctions POSIX: Ne pas tester pour le succès, le test de l'échec. fonctions POSIX que le retour d'aujourd'hui -1 en cas d'erreur retourne toujours exactement -1, donc j'utiliser l'un des deux chèques pour tous:

if (ret == -1) {
    perror(...);
}

// or

if (ret < 0) {
    perror(...);
}

(je préfère le premier, mais une seconde de plus générale ne me dérange pas.)

La comparaison des pages de manuel pour truncate et fflush, à la fois retour 0 en cas de succès, mais le retour des valeurs différentes pour l'erreur (troncature -> -1, fflush -> EOF). Donc, je vérifierais pour 0.

directives Cert semblent préférer le « ! = 0 » chèque comme cela est valable dans plusieurs de leurs exemples extraits de code.

Vérifiez toujours les pages de manuel pour les codes de retour.

En général, 0 signifie le succès, mais il existe des exceptions telles que printf().

Vérifier man 2 intro pour les codes errnos et erreur des appels système.

Quoi que vous fassiez, raccourci jamais un test pour le succès avec

if (!ret) 

Il est déroutant et quelqu'un (vous y compris) mal lu plus tard comme un test pour l'échec. Il est généralement préférable d'utiliser des tests explicites.

Si la définition est que 0 signifie le succès, et que vous voulez vérifier succès , alors vous devriez vérifier l'équivalence à 0. (ce qui est pour aucune autre raison que la lisibilité cisaillement)

Pour la plupart des fonctions de l'API POSIX, les valeurs négatives sont des erreurs. Donc, je test pour l'échec avec if (ret < 0).

Ma règle de base est que les fonctions comme celles-ci renvoient le code d'erreur (ou tout simplement si une erreur est survenue) par la valeur de retour. Donc, pour moi il est logique qu'une valeur de retour de 0 signifie qu'il n'y avait rien de ce genre pour revenir et qu'aucune erreur. Par conséquent, je vérifie juste si la valeur de retour est 0 si je veux tester si la fonction a réussi, et si non seulement vérifier ce que la valeur d'erreur était et agir en conséquence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top