2015-07-26 12 views
8

Ho un progetto C++ che compilo sia usando g++ sulla mia macchina (compilando su "host") sia con un processore ARM usando un cross-compilatore (nel mio caso arm-cortex_a8-linux-gnueabi-g++). Sono in fase di conversione in C++ 0x/11 standart e non v'è un errore che ottengo quando si compila la lista di inizializzazione, che sono stato in grado di riprodurre nel seguente frammento:"Restringimento della conversione da 'int' a 'char' all'interno di {}" per valori legali durante la compilazione incrociata

int main(void) { 
    char c[1] = {-108}; 
} 

Questo programma è apparentemente corretta come -108 è un valore legale per char. Compilazione questo con g++ cede nessun errore con la seguente riga di comando:

g++ example.cc -std=c++0x 

Tuttavia, quando compilo con il cross-compilatore, in questo modo:

arm-cortex_a8-linux-gnueabi-g++ example.cc -std=c++0x 

ottengo il seguente errore:

example.cc: In function 'int main()': 
example.cc:2:22: error: narrowing conversion of '-0x0000000000000006c' from 'int' to 'char' inside { } [-fpermissive] 

Poiché il valore è legale, questo sembra un bug. Puoi spiegare perché ottengo questo errore e cosa devo fare per risolverlo?

Modifica: nota che l'utilizzo di valori positivi (ad es., 108) è legale e non genera un errore su entrambi i compilatori.

+0

'char' potrebbe essere non firmato sulla piattaforma di destinazione. Puoi controllare? – Brian

+0

@ Brian, come posso verificarlo? –

+0

@AndyThomas 'std :: is_signed '? O, in modo rustico, 'char (-1) <'\ 0'' – Columbo

risposta

14

Quando si dichiara una variabile come char, dipende dall'implementazione indipendentemente dal fatto che sia firmata o non firmata. Se è necessario essere in grado di memorizzare valori negativi, è necessario dichiararlo in modo esplicito signed anziché fare affidamento sull'impostazione predefinita definita dall'implementazione.

signed char c[1] = { -108 }; 
9

Since the value is legal

Come lo sai? Il grado di firma char è definito dall'implementazione. E se è firmato, il codice è mal formato da restringimento - §8.5.4/7:

A narrowing conversion is an implicit conversion
[…]
(7.4) — from an integer type […] to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

§8.5.1/2:

If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed.

Tuttavia, se avete bisogno di un firmato char , utilizzare signed char.

signed char c[1] = {-108}; 

... è garantito per funzionare.

-1

Questo dovrebbe essere ancora meglio:

signed char c[] = { (signed char)(-108) }; 

Perché tra parentesi il valore potrebbe essere trattata come int per impostazione predefinita.

Problemi correlati