2015-11-23 7 views
11

Abbiamo avuto un bug nel nostro codice proveniente dalla lineaC++: avviso necessario per: unsigned int i = -1;

unsigned int i = -1; 

Quando il codice è stato scritto originariamente, è stato i = 0 e quindi corretta. Usando -Wall -Wextra, mi ha un po 'sorpreso che gcc non mi ha avvisato qui perché -1 non si adatta a un int unsigned.

Solo quando si accende -Wsign-conversion questa riga diventa un avviso, ma con esso molti molti falsi positivi. Sto usando una libreria di terze parti che esegue operazioni di tipo array con int signed (anche se non possono essere < 0), quindi ogni volta che lo mesco con ad es. vettore, ottengo avvertimenti - e non vedo il punto di aggiungere milioni di caste (e anche le intestazioni di terze parti producono molti avvertimenti). Quindi sono troppi avvertimenti per me. Tutti questi avvertimenti sono che la conversione "può cambiare il segno". Va bene perché so che non succede in quasi tutti i casi.

Ma con l'assegnazione di cui sopra, ottengo lo stesso avviso "può cambiare". Questo non dovrebbe essere "cambierà sicuramente segno!" invece di "può cambiare"? C'è un modo per emettere avvisi solo per questi casi "cambieranno", non per i casi forse?

+1

Anche il cambio di segno definito viene spesso utilizzato deliberatamente. Ad esempio, 'std :: string' ha' static const size_type npos = -1; '. – interjay

+1

[-1 viene utilizzato con tipi senza segno] (http: // stackoverflow.it/q/22801069/1708801) poiché il suo risultato è ben definito dallo standard. –

+0

utilizzando unsigned per assicurarti che la variabile non sia negativa è un altro errore: D –

risposta

5

Inizializza con parentesi graffe:

unsigned int i{-1}; 

uscite GCC:

main.cpp:3:22: error: narrowing conversion of '-1' 
from 'int' to 'unsigned int' inside { } [-Wnarrowing] 
    unsigned int i{-1};

noti che non provoca sempre un errore, potrebbe essere un avvertimento o disattivata del tutto. Dovresti provarlo con la tua vera toolchain.

+0

Fornire i flag di compilazione per migliorare la risposta. – YSC

+1

@ YSC Si tratta di un errore, quindi qualsiasi flag lo farà :) – Quentin

+1

È [mal formato e non è necessario che sia un errore] (http://stackoverflow.com/a/31685448/1708801) –

1

Ma con l'assegnazione di cui sopra, ottengo lo stesso avviso "può cambiare". Questo non dovrebbe essere "cambierà sicuramente segno!" invece di "può cambiare"?

Questo è strano. Ho provato un paio di versioni di gcc nel range di (4,6-5,2) e hanno fatto dare un avvertimento diverso per unsigned int i = -1;

avvertimento: intero negativo convertito in modo implicito tipo unsigned [-Wsign-conversione]

detto questo, sono effettivamente controllati dalla stessa opzione come il può cambiare segno avvertimenti, quindi ...

esiste un modo per emettere avvertimenti solo per queste "cambierà" casi, non per forse casi?

Per quanto ne so, non è possibile. Sono sicuro che sarebbe possibile implementare nel compilatore, quindi se si desidera un'opzione separata per abilitare l'avviso per l'assegnazione di un numero negativo, noto in fase di compilazione, a una variabile non firmata, è possibile inviare una richiesta di funzionalità. Tuttavia, poiché assegnare una variabile unsigned a -1 è una cosa così comune e solitamente perfettamente valida, dubito che tale funzionalità sia considerata molto importante.

+0

Ok, grazie per la risposta. In effetti, il testo di avvertenza è diverso. Stavo solo guardando la linea sbagliata tra tutti gli altri avvertimenti "potrebbe". Quindi sembra che la mia soluzione preferita sia usare sempre più variabili "auto". – Raubtier

Problemi correlati