Domanda

Stavo scansionando un codice sorgente di terze parti usando Findbugs (solo per essere cauto prima di integrarlo nel mio) e ho trovato il seguente avviso:

long a = b << 32 | c
  

Bug: spostamento intero di 32 ID modello:   ICAST_BAD_SHIFT_AMOUNT, digitare: BSHIFT,   categoria: CORRETTEZZA

     

Il codice esegue uno spostamento intero di   una quantità costante al di fuori dell'intervallo   0..31. L'effetto di questo è di usare i 5 bit inferiori del valore intero   per decidere quanto passare. Questo   probabilmente non era previsto era previsto, e   almeno confuso.

Qualcuno potrebbe spiegare cosa significa esattamente quanto sopra?

Grazie! (Sono un principiante nella programmazione Java)

È stato utile?

Soluzione

Dalle Specifiche del linguaggio Java :

  

Se il tipo promosso dell'operando di sinistra è int, come distanza di spostamento vengono utilizzati solo i cinque bit di ordine più basso dell'operando di destra. È come se l'operando di destra fosse sottoposto a un operatore AND logico bit a bit & amp; (§15.22.1) con il valore di maschera 0x1f. La distanza di spostamento effettivamente utilizzata è quindi sempre nell'intervallo da 0 a 31, incluso.

Quindi se b è un int, l'espressione è identica a

long a = b | c;

di cui dubito fortemente sia ciò che si intende. Probabilmente avrebbe dovuto essere

long a = ((long) b << 32) | c;

(Se b è già lungo, il codice è corretto e FindBugs si sbaglia sul bug).

Altri suggerimenti

Modificato: Il problema quasi sicuramente deriva dal fatto che 'b' è un 'int' e non un 'lungo'.

In C, se 'b' è un numero intero anziché un lungo e si sposta a sinistra di 32 bit, tutti i bit dal valore originale sono stati rimossi, quindi il risultato dell'espressione complessiva sarebbe lo stesso come 'c' invocheresti un comportamento indefinito, quindi ogni risultato è consentito. Java definisce le cose in modo diverso - come osservato nel commento di Rasmus Faber e nella risposta scelta - e fa turni troppo lunghi modulo il numero massimo di bit che possono essere spostati. [Sembra uno strano modo di fare affari; Probabilmente avrei organizzato un'eccezione in una lingua che li ha. Tuttavia, è chiaramente definito, il che è più importante dell'esatta definizione.] La coercizione a 64 bit non si verifica mentre viene valutata l'espressione; si verifica quando l'espressione è completa e l'assegnazione avviene.

Il riferimento a 5 bit è ... intrigante. Significa che se si sposta a sinistra di, diciamo, 48 o 110000 binario, equivale a spostare a sinistra di 16. O, in alternativa, ' x < < n 'è uguale a' x < < (n% 32) '.

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