Domanda

Sono necessari disallineamenti firmati/non firmati?

Ecco il mio programma:

int main(int argc, char *argv[]) {
    unsigned int i;

    for (i = 1; i < argc; i++) { // signed/unsigned mismatch here

    }
}

argc è firmato, i non è. È un problema?

È stato utile?

Soluzione

"I disallineamenti firmati/non firmati" possono essere cattivi. Nella tua domanda, stai chiedendo dei confronti. Quando si confrontano due valori dello stesso tipo di base, ma uno firmato e uno non firmato, il valore firmato viene convertito in non firmato. Così,

int i = -1;
unsigned int j = 10;

if (i < j)
    printf("1\n");
else
    printf("2\n");

Stampa 2, non 1. Questo perché in i < j, i viene convertito in un unsigned int. (unsigned int)-1 è uguale a UINT_MAX, un numero molto grande. La condizione valuta quindi false e si arriva al else clausola.

Per il tuo esempio particolare, argc è garantito per essere non negativo, quindi non devi preoccuparti della "mancata corrispondenza".

Altri suggerimenti

Non è un vero problema nel tuo caso particolare, ma il compilatore non può sapere che Argc avrà sempre valori che non causano problemi.

Non è male. Risolverei gli avvisi di compilatore riguardanti la mancata corrispondenza firmata/non firmata perché possono accadere cose cattive anche se sono improbabili o impossibili. Quando devi correggere un bug a causa della mancata corrispondenza firmata/non firmata, il compilatore sta fondamentalmente dicendo "te l'ho detto". Non ignorare l'avvertimento è lì per un motivo.

È solo indirettamente un problema.

Cose brutte possono accadere se usi numeri interi firmati per operazioni bitwise come &, |, << e >>.
Possono accadere cose cattive completamente diverse se usi numeri interi non firmati per aritmetica (underflow, anelli infiniti quando si verifica se un numero lo è >= 0 eccetera.)

Per questo motivo, alcuni compilatori e strumenti di controllo statici emetteranno avvertimenti quando si mescolano numeri interi firmati e non firmati in entrambi i tipi di operazione (aritmetica o manipolazione di bit.)

Sebbene possa essere sicuro mescolarli in casi semplici come il tuo esempio, se lo fai significa che non è possibile utilizzare quegli strumenti di controllo statici (o devono disabilitare tali avvertimenti) che possono significare che altri bug non vengono rilevati.

A volte non hai scelta, ad esempio quando fai aritmetica sui valori di tipo size_t nel codice di gestione della memoria.

Nel tuo esempio mi attenerei int, solo perché è più semplice avere meno tipi e il int ci sarà comunque dentro in quanto è il tipo del primo argomento main().

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