Domanda

Una presentazione stile di codifica che ho partecipato ultimamente in carica ha sostenuto che le variabili non devono essere assegnati (per un valore di default) quando essi sono definiti. Invece, essi dovrebbero essere assegnato un valore di default poco prima del loro utilizzo. Quindi, qualcosa come

int a = 0;

dovrebbe essere visto di buon occhio.

Ovviamente, un esempio di 'int' è semplicistico, ma la stessa segue per altri tipi anche come puntatori ecc.

Inoltre, è stato anche detto che i compilatori compatibili C99 ora lanciano un avvertimento nel caso di cui sopra.

L'approccio di cui sopra sembra utile solo a me per le strutture ossia li memset solo prima dell'uso. Questo sarebbe efficace se si utilizza la struttura (o riempito) soltanto in una gamba errore.

Per tutti gli altri casi, trovo la definizione e l'assegnazione di un valore predefinito un esercizio di prudenza come ho incontrato un sacco di bug a causa di puntatori non inizializzato sia durante la scrittura e il mantenimento di codice. Inoltre, ritengo C ++ tramite costruttori sostiene anche lo stesso approccio cioè definire e assegnare.

Mi chiedo il motivo per cui (se) di serie C99 non piace la definizione e l'assegnazione. È la loro alcun merito considerevole nel fare ciò che la presentazione stile di codifica sostenuto?

È stato utile?

Soluzione

Di solito io consiglierei di inizializzazione delle variabili quando vengono definiti se il valore che dovrebbero avere è noto, e lasciare le variabili non inizializzate se il valore non è. In entrambi i casi, ha messo il più vicino al loro uso come regole di visibilità consentono.

  

Al contrario, essi dovrebbero essere assegnato un valore di default poco prima del loro utilizzo.

Di solito non si dovrebbe usare un valore di default a tutti. In C99 si possono mescolare il codice e le dichiarazioni, quindi non c'è alcun punto di definizione della variabile prima di assegnare un valore ad essa. Se si conosce il valore che si suppone di prendere, allora non c'è alcun punto di avere un valore di default.

  

Inoltre, è stato anche detto che i compilatori compatibili C99 ora lanciano un avvertimento nel caso di cui sopra.

Non per caso si mostra - non si ottiene un messaggio di avviso per avere int x = 0;. Ho il forte sospetto che qualcuno ha ottenuto questo mescolato. I compilatori avvertono se si utilizza una variabile senza assegnare un valore ad essa, e se si dispone di:

... some code ...

int x;

if ( a )
    x = 1;
else if ( b )
    x = 2;
// oops, forgot the last case else x = 3;

return x * y;

quindi si otterrà un avviso che x possono essere utilizzati senza essere inizializzato, almeno con gcc.

Non sarà possibile ottenere un messaggio di avviso se si assegna un valore alla x prima della if, ma è irrilevante se l'assegnazione è fatto come un initialiser o come una dichiarazione separata.

Se non avete una ragione particolare per assegnare il valore due volte per due dei rami, non c'è nessun punto assegnando il valore di default di x prima, come si ferma il compilatore che avvisa che hai coperto ogni ramo.

Altri suggerimenti

C'è non tale requisito (o anche linea guida che io sappia) in C99, né il compilatore vi avverto su di esso. E 'semplicemente una questione di stile.

Per quanto riguarda la codifica stile è interessato, penso che hai preso le cose troppo alla lettera. Ad esempio, la sua dichiarazione è proprio nel seguente caso ...

int i = 0;

for (; i < n; i++)
        do_something(i);

... o anche in ...

int i = 1;

[some code follows here]

while (i < a)
        do_something(i);

... ma ci sono altri casi che, nella mia mente, sono meglio manipolato con una precoce "dichiarare e assegnare". Considerate le strutture costruite sullo stack o vari costrutti OOP, come in:

struct foo {
        int bar;

        void *private;
};

int my_callback(struct foo *foo)
{
        struct my_struct *my_struct = foo->private;

        [do something with my_struct]

        return 0;
}

O come in (C99 inizializzatori struct):

void do_something(int a, int b, int c)
{
        struct foo foo = {
                .a        = a,
                .b        = b + 1,
                .c        = c / 2,
        };

        write_foo(&foo);
}

I sorta di accordo con il consiglio, anche se non sono del tutto sicuro che la norma dice nulla al riguardo, e ho molto dubbio il po 'di avvisi del compilatore è vero.

La cosa è, i compilatori moderni possono e di rilevare l'uso di variabili non inizializzate. Se si imposta le variabili a valori di default a inizializzazione, si perde che il rilevamento. E i valori di default possono causare bug troppo; certamente nel caso del vostro esempio, int a = 0;. Chi dice 0 è un valore appropriato per a?

Nel 1990, il consiglio Sarebbe stato sbagliato. Al giorno d'oggi, è corretto.

Lo trovo molto utile per pre-assegnare alcuni dati di default alle variabili in modo che io non devo fare (come molti) i controlli nulli nel codice.

Ho visto così tanti bug a causa di puntatori non inizializzati che ho sempre sostenuto di dichiarare ogni variabile con NULL_PTR e ogni primitivewith qualche valore non valido / default.

Dal momento che io lavoro su RTOS e sistemi ad alte prestazioni ma a basso risorse, è possibile che i compilatori che utilizziamo non cattura l'utilizzo non inizializzato. Anche se dubito che i compilatori moderni possono anche essere fatti valere al 100%.

In progetti di grandi dimensioni in cui sono ampiamente utilizzati del Macro, ho visto scenari rari dove anche Kloclwork / Purify sono riusciti a trovare non inizializzata l'utilizzo.

Allora io dico attaccare con esso fino a quando si utilizza pianura vecchio C / C ++.

lingue moderne come .Net possono garantire per inizializzare varaibles, o dare un errore di compilazione per l'utilizzo variabile non inizializzata. Seguente link fa un analisi delle prestazioni e convalida che v'è una performance del 10-20% colpire for .NET. L'analisi è in modo del tutto particolare e è spiegato bene.

http://www.codeproject.com/KB/dotnet/DontInitializeVariables.aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top