2015-12-07 10 views
5

Sto giocando con Memory Sanitizer con Clang 3.7.0 su Ubuntu 14.04. Il seguente codice funziona perfettamente:Memory Sanitizer

#include <cstdio> 

int main() { 
    double ans; 
    printf("Hello World: %f\n", ans); 

    return 0; 
} 

quando si compila con

clang++ -g -O1 -fsanitize=memory -fsanitize-memory-track-origins=2 -fomit-frame-pointer sanitize.cpp -o sanitize 

mi aspettavo un errore. Memory Disintegratore non riconosce il fatto che ans non è stato inizializzato?

Grazie per il vostro aiuto.

+0

prova a cambiare ans in un char *! – Matt

+0

@Matt: WTF? –

+0

Downvoted a causa della mancanza evidente di qualsiasi ricerca. –

risposta

5

Dalla documentazione di santitizer clang è chiaro che si tratta solo di letture di memoria unitializzate dalla memoria allocata dinamicamente. La memoria automatica non fa parte dei controlli del disinfettante.

+0

Grazie. Capisco ora che la mia domanda è stata stupida in quanto questo tipo di controllo può essere effettuato staticamente. – InsideLoop

0

Il memroit di Valgrind potrebbe essere un'opzione per rilevare i valori di stack non inizializzati.

Valgrind documentazione:

Per valori non inizializzate provenienti da un blocco mucchio, MemCheck mostra dove il blocco è stato assegnato. Per i valori non inizializzati provenienti da un'allocazione dello stack, Memcheck è in grado di indicare quale funzione ha assegnato il valore, ma non di più, in genere mostra la posizione di origine della parentesi aperta della funzione. Quindi dovresti controllare attentamente che tutte le variabili locali della funzione siano inizializzate correttamente.

Riferimento: http://valgrind.org/docs/manual/mc-manual.html

1

Non è necessario alcun disinfettante per la cattura di questo errore. Il compilatore può capire questo errore in fase di compilazione (disinfettanti e valgrind funzionano in fase di esecuzione). In effetti, tutti i GCC Clang e ICC daranno un avvertimento per questo codice se si attivano gli avvertimenti. Questo avviso particolare è controllato con il flag -Wuninitialized. In generale, è buona norma usare sempre un livello di avviso elevato. Mi sento di raccomandare la seguente combinazione di segnali di avvertimento, soprattutto mentre l'apprendimento della lingua:

-Wall -Wextra -pedantic 

Se si ottiene alcuni falsi positivi, solo dopo aver rigorosamente il controllo che sono in realtà false, è possibile disattivare gli avvisi specifici. Non c'è motivo per non usare le bandiere di avvertimento. Alcuni progetti utilizzano addirittura il flag -Werror, trasformando tutti gli avvisi in errori.