Domanda

Ho avuto uno sguardo a questa pagina: http://www.devbistro.com/tech-interview-questions/Cplusplus.jsp, e non capisco questa domanda:

Ciò che potenzialmente sbagliato con il seguente codice?

long value;
//some stuff
value &= 0xFFFF;

Nota:Suggerimento per il candidato sulla base della piattaforma che stiamo sviluppando per.Se la persona continua a non trovare niente di sbagliato con il codice, non sono esperto con il C++.

Qualcuno può elaborare su di esso?

Grazie!

È stato utile?

Soluzione

Diverse risposte qui affermano che se un int ha una larghezza di 16 bit, 0xFFFF è negativo. Questo non è vero. 0xFFFF non è mai negativo.

Un esadecimale letterale è rappresentato dal primo dei seguenti tipi che è abbastanza grande per contenerlo:. int, unsigned int, long, e unsigned long

Se int ha una larghezza di 16 bit, allora 0xFFFF è maggiore del valore massimo rappresentabile da un int. Così, 0xFFFF è di tipo unsigned int, che è garantito per essere grande abbastanza per rappresentare 0xFFFF.

Quando le usuali conversioni aritmetiche vengono eseguiti per valutare l'&, il unsigned int viene convertito in un long. La conversione di 16 bit unsigned int a long è ben definita perché ogni valore rappresentabile da una a 16 bit unsigned int è rappresentabile da una a 32 bit long.

Non c'è alcuna estensione segno necessaria perché il tipo iniziale non è firmato, e il risultato dell'utilizzo di 0xFFFF è la stessa come il risultato di utilizzando 0xFFFFL.

In alternativa, se int è più ampio di 16 bit, allora 0xFFFF è di tipo int. Si tratta di una firma, ma positiva, il numero. In questo caso entrambi vengono firmato ed long ha il grado di conversione maggiore, quindi la int viene nuovamente promosso long dai soliti conversioni aritmetiche.


Come altri hanno detto, si dovrebbe evitare l'esecuzione di operazioni bit per bit su operandi firmato perché il risultato numerico dipende da come viene rappresentato signedness.

A parte questo, non c'è niente di particolarmente sbagliato con questo codice. Direi che si tratta di una preoccupazione stile che value non è inizializzato quando viene dichiarata, ma questo è probabilmente un commento livello pignoli e dipende dai contenuti della sezione //some stuff che è stato omesso.

E 'probabilmente anche preferibile utilizzare un carattere a dimensione fissa di tipo intero (come uint32_t) invece di long per la portabilità maggiore, ma in realtà anche questo dipende dal codice che si sta scrivendo e che cosa le vostre ipotesi di base sono.

Altri suggerimenti

Credo che a seconda delle dimensioni di un lungo del 0xFFFF letterale (-1) potrebbe essere promosso a una dimensione più grande e di essere un valore con segno sarà il segno esteso, potenzialmente diventando 0xffffffff (ancora -1).

Suppongo che sia perché c'è nessuna dimensione predefinita per un altro, di quanto deve essere grande almeno come la precedente risoluzione (int).Così, a seconda delle dimensioni, si potrebbe troncare il valore di un sottoinsieme di bit (se è lungo più di 32 bit) o di overflow (se è inferiore a 32 bit).

Sì, long (per la spec, e grazie per il promemoria nei commenti) deve essere in grado di tenere almeno -2147483647 a 2147483647 (LONG_MIN e LONG_MAX).

Per un valore non è inizializzato prima di fare il e quindi penso che il comportamento è indefinito, il valore potrebbe essere qualsiasi cosa.

dimensione tipo lungo è la piattaforma / compilatore specifico.

Che cosa si può qui dire è:

  1. È firmato.
  2. Non possiamo conoscere il risultato del valore di & = 0xFFFF; poiché potrebbe essere per esempio valore & = 0x0000FFFF; e non farà quello previsto.

Mentre si potrebbe sostenere che, poiché non è un buffer-overflow o qualche altro errore che è probabile che sia sfruttabile, è una style cosa e non un bug, sono il 99% fiducioso che la risposta che la questione-scrittore è alla ricerca di è che value è gestito prima che venga assegnato. Il valore sta per essere spazzatura arbitraria, ed è improbabile che sia quello che doveva, quindi è "potenzialmente sbagliato".

Utilizzare MSVC Penso che la dichiarazione avrebbe compiuto ciò che è stato molto probabilmente inteso - che è: cancellare tutti ma i 16 bit meno significativi di valore, ma ho incontrato altre piattaforme che interpretare il 0xffff letterale come equivalenti a (breve) -1, poi firmare estendersi a convertire a lungo, nel qual caso il "value = & 0xFFFF" dichiarazione non avrebbe alcun effetto. "Value = & 0x0FFFF" è più esplicito e robusto.

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