2010-09-07 4 views
5

J'ai une question de conception simple (?).C: Erreur de jet lors de la vérification des paramètres ou laissez-le toucher le ventilateur?

J'écris un programme simple, qui a quelques fonctions qui ressemblent à celles-ci. J'ai quelques questions à ce sujet, sans intention de réouvrir une guerre sainte.

Dois-je ajouter une vérification de santé mentale sur le n? Si oui, comment devrais-je informer l'appelant?

Renvoyer -1 semble étrange sur les flotteurs;

float foo(float *m,size_t n){ 
    if (n == 0) return -1f 

    ... 
    } 

Mon autre option est un paramètre sur

float foo(float *m,size_t n, int *error){ 

     if (n==0){ 
      *error = 1; 
      return 0f; 
     } 
     ... 
} 

mise à jour

C'est genre de un programme de jouet, juste essayer de pratiquer certaines choses. La question excède ce fait. Peut-être que je devrais reformuler à "comment gérer les erreurs sans (OOP) exceptions".

Envisager également de tester n avant de faire l'appel, mais ne l'aime pas autant.

Des pensées? Merci d'avance.

+0

Il peut être utile d'en savoir plus sur l'environnement des fonctions. Existe-t-il dans un corps de code avec des pratiques de vérification d'erreurs établies, ou lorsque le code d'un tiers a certaines attentes? Est-ce un projet de jouet autonome? – TSomKes

+1

@TsomKes a mis à jour ma question. – Tom

Répondre

6

Je suppose que votre option out parameter est bonne. Mais je suppose que ce serait mieux dans l'autre sens. Utilisez le paramètre out pour obtenir le résultat et la valeur de retour pour indiquer l'état de l'appel. Comme cette

int foo(float *m, size_t n, float* result) 
{ 
    if(someFailureCondition) 
    return ERROR; // ERROR being an error integer 
    // else 
    // do some calculation 
    // set your result 
    return NO_ERROR; // NO_ERROR being an integer 
} 

Edit: La valeur de retour peut être plus prolixe pour indiquer l'état actuel du paramètre out. Voir le commentaire de Jamesdlin!

+0

Merci, n'a pas considéré celui-là. Semble plus élégant. – Tom

+1

Je préfère aussi ce style pour vérifier les erreurs d'exécution, mais vous devez également indiquer explicitement (dans le cadre du contrat de la fonction) l'état des paramètres de sortie en cas d'échec (par exemple, ils sont dans un état indéfini, à une valeur spécifique). – jamesdlin

2

Si -1 n'est quand même pas renvoyé par la fonction, retournez -1. Mais si passer n = 0 ne casse pas la fonction, alors ce n'est pas vraiment nécessaire. Je suppose que n est la taille du tableau m.

Les erreurs de manipulation sont une question de préférence. OpenGL gère les erreurs en renvoyant un code d'erreur (-1 ou autre) lorsqu'une fonction échoue. Le code d'erreur est renvoyé par l'appel à GetLastError() (ou quelque chose comme ça). Cela semble être une solution idéale de gestion des erreurs.

+0

oui, n est le nombre d'éléments dans m. – Tom

1

Il y a des valeurs de virgule flottante spéciaux que vous pouvez utiliser si vous voulez - par exemple, si votre implémentation à virgule flottante supporte NaN silencieux (Not-a-Number), vous pouvez utiliser la NAN macro de math.h:

#include <math.h> 
float foo(float *m,size_t n) 
{ 
    if (n == 0) return NAN; 

    ... 
} 
+0

Considéré, mais n'est-ce pas le cas "ne rien faire"? – Tom

+0

Je ne suis pas sûr de ce que vous voulez dire. Il est supposé être similaire à votre cas '-1f', sauf que vous le tester avec' isnan() ', et il se propagera par le biais des calculs à virgule flottante suivants. – caf

1

Vous devez informer les appelants de la sémantique de votre fonction en documentant clairement votre code.

Quel est le contrat pour votre fonction? Si les appelants ne doivent pas passer 0 pour n, cela doit être expliqué et la fonction doit utiliser assert pour vérifier que ces conditions sont remplies.Les erreurs logiques devraient être détectées tôt, et ces défaillances devraient être aussi spectaculaires que possible.

Maintenant, si vous écrivez du code pour une bibliothèque qui seront consommés par d'autres développeurs et craignent que les gens vont compiler avec assert désactivé, il est raisonnable de combiner cela avec un mode de défaillance plus doux qui est toujours activé:

if (n == 0) 
{ 
    assert(0); 
    return NAN; /* Or return some error code */ 
} 
Questions connexes