2009-04-01 6 views
2

Je veux savoir si vérifier les codes de retour pour toutes les fonctions que nous écrivons pour l'environnement de production. pour e, g, j'utilise beaucoup et saisis aussi les codes de retour pour la bibliothèque standard, pas seulement les fonctions que vous écrivez, mais aussi l'API tierce/bibliothèque standard/toute autre bibliothèque.Attraper les codes de retour dans les environnements de production?

La plupart des codes que je vois en production ne le font pas. Donc, ma question s'adresse aux personnes expérimentées qui ont travaillé dans des environnements de production et qui écrivent du code de production depuis une vingtaine d'années. Est-ce que vous attrapez le code de retour de l'API/bibliothèque standard/de toute autre bibliothèque, et pas seulement des fonctions que vous implémentez? Par exemple, disons que vous attrapez des codes de retour pour les fonctions lib standard C (snprintf/sprintf, strncat/strcat et ainsi de suite .., ..) de la bibliothèque standard C.

Merci pour toutes vos réponses.

Répondre

3

Je ne pense pas que vous devriez adopter une approche «tout ou rien». Capture des codes retour/erreur lorsque vous attendez problèmes avec l'appel de la fonction (ou, bien sûr, si votre calcul ultérieur dépend de ce que la fonction retourne). Toutefois, si vous êtes sûr que l'appel ne peut pas entraîner d'erreurs (ou que vous n'avez aucune utilité pour la valeur de retour, même sinon), ignore en ignorant la valeur renvoyée.

Il s'agit de l'un des domaines dans lesquels le jugement technique d'un individu, et non une «meilleure pratique» prescrite, doit être utilisé. De plus, je pense que la même pensée s'appliquerait au traitement des exceptions.

+0

oui donc c'est plus d'un art ..que de la science ... –

+0

Pas du tout d'accord. À quelques exceptions près, vous devriez toujours vérifier les codes de retour, même si vous ne vous attendez pas à des problèmes. Parce que parfois des problèmes se produisent là où vous ne les attendiez pas. Et déboguer un problème qui résulte d'une panne non détectée ailleurs peut être un cauchemar ... – sleske

+0

Méthode très dangereuse: "tous les programmeurs sont optimistes" Ils pensent toujours qu'une erreur ne peut pas se produire et, quand elle le fait .... Je vote pour vérifier . – bortzmeyer

0

snprintf est utile, comme vous voudrez peut-être allouer un tampon plus grande puis nouvelle tentative, ou vous pouvez être l'appeler dans une séquence:

// cons lists as [a,b,c, ...] 
if (type == kin_cons_class()) { 
    size_t offs = snprintf (buf, max, "["); 

    if (offs >= max) 
     return nul_terminate (buf, offs, max); 

    size_t count = depth; 

    kin_cons_ref_t empty = kin_cons_nil(); 
    kin_cons_ref_t cons; 

    for (cons = ref; cons != empty; cons = kin_cons_tail (cons)) { 
     if (count > 15) { 
      offs += snprintf (buf + offs, max - offs, ", ..."); 

      break; 
     } 

     if (cons != ref) { 
      offs += snprintf (buf + offs, max - offs, ","); 

      if (offs >= max) 
       return nul_terminate (buf, offs, max); 
     } 

     offs += string_repr (buf + offs, max - offs, kin_cons_head (cons), depth, escape_strings); 

     if (offs >= max) 
      return nul_terminate (buf, offs, max); 

     ++count; 
    } 

    if (offs >= max) 
     return nul_terminate (buf, offs, max); 

    offs += snprintf (buf + offs, max - offs, "]"); 

    return nul_terminate (buf, offs, max); 
} 

Si vous continuez sans tous les offs >= max tests, vous obtenez un tampon débordement et il va segfault.

Cela ne se produit pas avec printf, il est donc moins courant de vérifier le retour.

Si vous devez modifier votre comportement en fonction du fonctionnement d'une fonction, vérifiez le retour. De nombreuses fonctions de bibliothèque standard peuvent échouer ou provoquer un comportement indéfini plus tard, vous devez donc vérifier ces retours.

Si vous n'avez pas besoin de modifier le comportement en fonction de la valeur de retour, il est inutile de le vérifier.

2

Si la fonction peut renvoyer un code d'erreur - vérifiez toujours et manipulez-le, aussi simple que cela. Cette règle peut vous faire gagner beaucoup de temps lors de la chasse aux bogues.

Si la fonction renvoie toujours le code qui ne peut pas indiquer l'erreur et que vous n'avez pas besoin du résultat (comme printf), vous pouvez bien sûr l'ignorer.

+0

Cette approche est la différence entre un programme qui plante juste et un programme qui se termine aussi gracieusement que possible avec des journaux d'erreurs indiquant ce qui s'est mal passé. – Harvey

+0

Non. Toutes les erreurs dans les fonctions standard ne provoquent pas de plantages, et vous passerez de longues heures à chercher l'origine du problème. Été là, fait cela. Je n'ai pas aimé ça. – qrdl

3

Il m'a fallu beaucoup de temps pour apprendre cela, mais à quelques exceptions près, vous devriez toujours vérifier le code retour d'une fonction.

J'ai vu beaucoup trop de code qui appelle malloc (par exemple) et utilise simplement avec bonheur le pointeur qu'il retourne. 99,9% du temps, ce n'est pas un problème, mais parfois malloc échouera et votre programme se bloquera lorsque vous essayez de déréférencer un pointeur NULL.Maintenant, on pourrait dire que vous voulez quitter si malloc renvoie NULL de toute façon - et c'est peut-être vrai, mais vous devriez toujours essayer de quitter normalement, même en cas d'erreur fatale. Donc, oui: vérifiez les codes de retour.

Ne supposez pas que quelque chose fonctionne parce que ça a toujours marché dans le passé. Les choses échouent tout le temps. Vous économiserez beaucoup de temps et de chagrin en codant défensivement, en vérifiant les erreurs, en vérifiant errno, en sortant strerror et en échouant gracieusement.

1

Si la fonction renvoie un code d'erreur, votre code d'appel devrait décider comment gérer une erreur. Pour certains programmes, ignorer l'erreur peut être OK; cela a tendance à être ce que les gens font avec les erreurs de la bibliothèque d'E/S standard lors de l'écriture sur stderr, par exemple. (Que pouvez-vous faire si le message a échoué? Quitter? Est-ce que vous le faites de toute façon?)

Une source de nuisance sont les fonctions documentées pour renvoyer une valeur mais toujours retourner la même valeur (généralement 0). Souvent, il s'agit de fonctions écrites à l'origine en K & R C avant le retour void. Ils ont été convertis en int puis un 'return(0);' a été ajouté pour supprimer les avertissements sur 'la fonction ne renvoie pas de valeur', plutôt que de le convertir en void comme il aurait dû l'être. Ces fonctions devraient être révisées à void; dans l'intervalle, il est possible d'ignorer leur valeur de retour d'erreur.

Je ne suis pas d'accord avec l'observation dans une autre réponse "capture retour/codes d'erreur lorsque vous attendez des problèmes avec l'appel de la fonction". Le problème est précisément l'inattendu, c'est ce qui vous tue. Même la plus stable des opérations peut échouer de manière inattendue (peut-être que le SGBD a planté, donc même si vous avez eu une connexion, vous n'en avez plus), et votre logiciel doit reconnaître et gérer ces problèmes.

2

Oui, à quelques exceptions près, votre programme devrait toujours vérifier et gérer les valeurs de retour d'erreur, même (surtout) si vous ne vous attendez pas à des erreurs. L'environnement de notre logiciel est souvent moins fiable que nous le souhaiterions, après tout. Incidentiellement, c'est pourquoi la plupart des langages modernes ont des exceptions: entre autres, ils fournissent un "gestionnaire d'erreur par défaut" (abandon et pile) pour les erreurs que vous ne gérez pas (c'est-à-dire catch). Ils permettent également de centraliser le traitement des erreurs, au lieu de vérifier la valeur de retour de chaque appel de fonction.

Questions connexes