C: errore di tiro su controllo dei parametri o lasciarlo colpito il ventilatore?
-
01-10-2019 - |
Domanda
Ho un design semplice (?) Domanda.
Sto scrivendo un semplice programma, che ha un paio di funzioni che sembrano questi.
float foo (float* m,size_t n){
float result;
//do some calculations, for example a sum
return result / n;
}
Ho un paio di domande su questo, senza alcuna intenzione di ri aprendo qualche guerra santa.
dovrebbe aggiungo un controllo di integrità sul n
? Se sì, come dovrei far conoscere al chiamante?
Tornando -1
sembra strano su carri;
float foo(float *m,size_t n){
if (n == 0) return -1f
...
}
La mia altra opzione è un parametro out
float foo(float *m,size_t n, int *error){
if (n==0){
*error = 1;
return 0f;
}
...
}
Aggiorna
Questa è tipo di un programma di giocattoli, solo cercando di praticare alcune cose. Le excedes questione questo fatto. Forse dovrei riformulare a "come gestire gli errori senza (OOP) eccezioni".
Anche considerando il test n
prima di fare la chiamata, ma non mi piace tanto.
Qualche idea? Grazie in anticipo.
Soluzione
Credo che la vostra opzione out parameter
è un buon compromesso. Ma credo che sarebbe stato meglio il contrario. Utilizzare il parametro fuori per ottenere il risultato e il valore di ritorno per indicare lo stato della chiamata. Ti piace questa ??p>
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
}
Modifica Il valore di ritorno può essere più dettagliato per indicare lo stato attuale del parametro out. Vedi il commento di Jamesdlin!
Altri suggerimenti
Se -1 non sarebbe restituita dalla funzione comunque, con tutti i mezzi di ritorno -1. Ma se passando n = 0 non si romperà la funzione, allora non è realmente necessario. Presumo che n è la dimensione della matrice m.
Gestione degli errori è una questione di preferenza. OpenGL gestisce gli errori restituendo un codice di errore (-1 o meno) quando una funzione fallisce. Il codice di errore viene restituito througha chiamata a GetLastError () (o qualcosa di simile). Questo mi sembra una soluzione di gestione degli errori ideale.
Ci sono valori in virgola mobile speciali è possibile utilizzare se si vuole - per esempio, se i supporti di implementazione in virgola mobile NaN silenzioso (Not-a-Number), è possibile utilizzare la macro NAN
da math.h
:
#include <math.h>
float foo(float *m,size_t n)
{
if (n == 0) return NAN;
...
}
Si dovrebbe consentire ai chiamanti di sapere che cosa la semantica del vostro funzione sono da documentare chiaramente il vostro codice.
Qual è il contratto per la vostra funzione? Se chiamanti sono tenuti a non passare 0 per n
, allora deve essere spiegato, e la funzione dovrebbero utilizzare assert
per verificare che tali requisiti sono soddisfatti. errori logici dovrebbe essere diagnosticato precocemente, e quei fallimenti dovrebbe essere più spettacolare possibile.
Ora, se siete scrittura di codice per una libreria che sarà consumato da altri sviluppatori e sono preoccupati che la gente compilare con assert
disabilitata, allora è ragionevole che si combinano con un modo di rottura più morbida che è sempre abilitata:
if (n == 0)
{
assert(0);
return NAN; /* Or return some error code */
}