2009-11-13 18 views
5

Ho recentemente installato un ambiente MinGW + MSYS sul mio laptop per verificare come stanno le cose con il supporto di Netbeans C/C++. Tutto sembra funzionare bene, tuttavia, durante i miei test ho notato una differenza tra GCC e il compilatore cl.exe di Microsoft.GCC - non dovrebbe essere emesso un avviso?

Ecco un esempio di programma:

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

int main(void) { 
    int i_max = INT_MAX; 
    char c_max = CHAR_MAX, c; 

    c = i_max; 
    printf("i_max: %d, c_max: %d, c: %d\n", i_max, c_max, c); 
    return EXIT_SUCCESS; 
} 

L'output è:

i_max: 2147483647, c_max: 127, c: -1 

Come si può vedere nel codice di cui sopra, ho assegnare un int a un char. Non dovrebbe questo produrre un avvertimento che potrebbe verificarsi una possibile perdita di dati? Il compilatore di Microsoft (che ho configurato per essere molto severo) emette l'avviso mentre GCC non lo fa.

Qui ci sono le opzioni di GCC che uso:

-g -Werror -ansi -pedantic -Wall -Wextra 

Mi manca qualche opzione GCC per rendere i controlli orari di compilazione ancora più severe?

risposta

9

Siete alla ricerca di

-Wconversion 

dovreste chiedere uno sviluppatore gcc per le ragioni specifiche per cui alcuni avvertimenti non sono inclusi nel -Wall o -Wextra.

In ogni caso, queste sono le bandiere che uso:

-Wall -Wextra -Wmissing-prototypes -Wmissing-declarations -Wshadow 
-Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Wnested-externs 
-Winline -Wno-long-long -Wconversion -Wstrict-prototypes 

Come altri hanno sottolineato, il comportamento di -Wconversion cambiato con version 4.3 - il vecchio avvertimento circa prototipi costringendo una conversione di tipo è ora disponibile come -Wtraditional-conversion.

+1

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html Questo collegamento mostra cosa è incluso in Wall e Wextra. Perché wconversion non è un completo bug/bug. – Pod

+1

La mia opinione è che quegli avvertimenti sono un dolore nella retroguardia molto più spesso di quanto non capiscano qualcosa, e il mio senso delle decisioni politiche di GCC è che tendono a pensare anche in questo modo. Sarebbe una buona idea avere un'opzione -W che significava "controllare tutto, non importa quanto noioso", naturalmente. –

+1

non funziona per me. usando "gcc -g -Werror -ansi -pedantic -Wall -Wextra -Wconversion foo.c" con il codice sopra in foo.c non si ottiene alcun avviso con gcc 4.1.2 – Glen

2

-Wall doesn't quite mean -Wall, -Wextra è già sotto il fuoco per essere un po 'eccessivamente pedante.

Come ha detto Christoph, stai cercando -Versione. È bello scavare davvero in cosa -Wall e -Wextra si accendono realmente, e basta specificare i flag -W che vuoi nel tuo file make, specialmente se trattano gli avvertimenti come errori.

+0

se non ti piacciono gli avvertimenti sul confronto di firmness, disabilitalo; inoltre, avvisi severi potrebbero costituire un problema per le codebase legacy, ma se inizi da zero, non è davvero difficile rendere il tuo codice privo di avvisi - suppongo che alcune persone siano semplicemente pigre;) – Christoph

1

In C, l'assegnazione di un int a un carattere è legale.

Dato che è legale (ma probabilmente è poco sicuro) i diversi produttori di compilatori fanno cose diverse quando incontrano questo codice.

Immagino che MS sia semplicemente un pedante extra mentre i ragazzi del GCC hanno deciso che non vale nemmeno la pena di essere avvertito.

0

Penso che rientri nelle "Usuali conversioni aritmetiche" (6.3.1.8) o "Regole di promozione intera" (5.1.2.3 (?)), Ma non riesco a trovare il testo specifico che dice il comportamento che si ' il vedere è previsto.

2

C'è una piccola sfumatura nella tua domanda che non mi è immediatamente ovvia dal modo in cui è formulata.

Se pensate che GCC (in particolare GCC) dovrebbe inviare un avviso qui, allora alcune opzioni del compilatore potrebbero aiutare (vedere altre risposte).

Se si pensa qualsiasi compilatore dovrebbe emettere un avvertimento qui (e mi sembra di leggere quel sentimento nella sua domanda), poi ... beh, "avvertimenti" non sono in alcun modo vincolante o anche di fatto unificato . Non c'è "dovrebbe" qui. Assegnare un valore intero tipizzato più grande a un tipo più piccolo senza un cast esplicito è perfettamente legale in C. Overflow sulla conversione, produce un comportamento definito dall'implementazione (non è nemmeno UB :))

2

Non ho ricevuto un avviso/errore con -Wconversion entrambi. Tuttavia, se si dà un passaggio con qualcosa come splint si ottiene tre avvertimenti:

file.c: (in function main) 
file.c:9:5: Assignment of int to char: c = i_max 
    To make char and int types equivalent, use +charint. 
file.c:10:52: Format argument 2 to printf (%d) expects int gets char: c_max 
    file.c:10:32: Corresponding format code 
file.c:10:59: Format argument 3 to printf (%d) expects int gets char: c 
    file.c:10:39: Corresponding format code 

Finished checking --- 3 code warnings 

Se lei fa sul serio la cattura di tutti i gli errori si dovrebbe usare più di uno strumento.

+0

Tieni presente che, per un variadic funziona come printf(), un char sarà passato come un int, e quel% d è l'identificatore di formato giusto per ottenere il valore numerico. A% c stamperà il valore come carattere, con la differenza che tra "65" e "A". –

+0

Corretto (anche se un cast renderebbe esplicito e quindi rimuovere l'avviso). Il mio punto di vista era più sul fatto che più punti di vista sono importanti quando si cerca di chiudere il codice di errore/senza errori. – ezpz

Problemi correlati