2010-04-16 7 views
9

So che Visual Studio con le opzioni di debug riempirà la memoria con un valore noto. g ++ (qualsiasi versione, ma gcc 4.1.2 è la più interessante) ha qualche opzione che dovrebbe riempire una struttura POD locale non inizializzata con valori riconoscibili?È possibile riempire g ++ variabili POD non inizializzate con valori noti?

struct something{ int a; int b; }; 
void foo() { 
    something uninitialized; 
    bar(uninitialized.b); 
} 

Mi aspetto che il uninitialized.b sia una casualità imprevedibile; chiaramente un bug e facilmente trovato se l'ottimizzazione e gli avvisi sono attivati. Ma compilato con solo -g, nessun avviso . Un collega aveva un caso in cui il codice simile a questo funzionava perché lo stesso aveva un valore valido; quando il compilatore è stato aggiornato, ha iniziato a fallire. Pensava che fosse perché il nuovo compilatore stava inserendo valori noti nella struttura (molto il modo in cui VS riempie 0xCC). Nella mia esperienza personale, erano solo diversi valori casuali che non erano validi.

Ma ora sono curioso - c'è qualche impostazione di g ++ che potrebbe riempire la memoria che lo standard direbbe altrimenti dovrebbe essere non inizializzata?

risposta

3

Non penso che tale opzione/funzione esista in gcc/g ++.

Ad esempio, tutte le variabili globali (e statiche) risiedono nella sezione .bss, che viene sempre inizializzata a zero. Tuttavia, quelli non inizializzati sono inseriti in una sezione speciale all'interno dello .bss, per motivi di compatibilità.

Se si desidera che vengano azzerati, è possibile passare l'argomento -fno-common al compilatore. Oppure, se ne hai bisogno su base variabile, usa __attribute__ ((nocommon)).

Per heap, è possibile scrivere il proprio allocatore per eseguire ciò che è stato descritto. Ma per lo stack, non penso che ci sia una soluzione facile.

+0

Non credevo che la funzione esistesse, ma il manuale di gcc è lungo e profondo, e sono rimasto sorpreso da ciò che è nascosto lì prima. –

1

Non credo che g ++ rileverà tutti i casi come questo, ma lo sarà sicuramente Valgrind.

+0

Sì, altri strumenti di analisi sembrano essere la soluzione. Sembrava qualcosa che il compilatore poteva organizzare, ma non troppo sorprendente se non lo fosse. –

4

Qualsiasi C++ comiler in grado di inizializzare qualsiasi tipo POD al suo valore "zero" utilizzando la sintassi:

int i = int(); 
float f = float(); 
MyStruct mys = MyStruct(); 
// and generally: 
T t = T(); 

Se si vuole parlare di debug che è un'altra cosa ...

(A proposito , Penso che VS avesse tutta la memoria non inizializzata inizializzata a 0xCC quando in "modalità di debug, in modo che non importa dove si salti (es. Chiama un puntatore di funzione non valido) che non è il vero codice di programma/dati int3 viene sollevato.)

+4

Oppure, per coloro che desiderano creare C++ come Lisp, 'T t ((T()))' :-) –

+1

@James: Hai perfettamente ragione, ma questa sintassi mi mette in un dilemma. Non so cosa faccia più male guardarlo - i miei occhi o il mio cuore. :) – conio

+0

Sì, è possibile * inizializzare, ma non è stato così, quindi credo di essere davvero inclinato verso il debug di aiuto. Sembra che la soluzione si trovi al di fuori di g ++, comunque (valgrind et.al). –

Problemi correlati