Char é assinado ou não assinado por padrão?
Pergunta
No livro "Referência completa de C", é mencionado que char
é por padrão não assinado.
Mas estou tentando verificar isso com o GCC e o Visual Studio. Está tomando como assinado por padrão.
Qual está correto?
Solução
O livro está errado. O padrão não especifica se claro char
é assinado ou não assinado.
De fato, o padrão define três tipos distintos: char
, signed char
, e unsigned char
. Se você #include <limits.h>
E então olhe para CHAR_MIN
, você pode descobrir se claro char
é signed
ou unsigned
(E se CHAR_MIN
é menor que 0 ou igual a 0), mas mesmo assim, o Três tipos são distintos No que diz respeito ao padrão.
Observe isso char
é especial dessa maneira. Se você declarar uma variável como int
É 100% equivalente a declarar como signed int
. Isso sempre é verdade para todos os compiladores e arquiteturas.
Outras dicas
Como Alok aponta, o padrão deixa isso até a implementação.
Para o GCC, o padrão é assinado, mas você pode modificar isso com -funsigned-char
. Nota: Para o GCC no Android NDK, o padrão não é assinado. Você também pode pedir explicitamente personagens assinados com -fsigned-char
.
No MSVC, o padrão é assinado, mas você pode modificar isso com /J
.
C99 N1256 Draft 6.2.5/15 "Tipos" tem a dizer sobre a assinatura do tipo char
:
A implementação deve definir char para ter o mesmo intervalo, representação e comportamento como char assinado ou char não assinado.
E em uma nota de rodapé:
CHAR_MIN
, definido em<limits.h>
, terá um dos valores0
ouSCHAR_MIN
, e isso pode ser usado para distinguir as duas opções. Independentemente da escolha feita,char
é um tipo separado dos outros dois e também não é compatível com.
De acordo com o livro de idiomas de programação C de Dennis Ritchie, que é o livro padrão de fato para Ansi C, Plain Chars assinado ou não assinado dependem da máquina, mas os caracteres imprimíveis são sempre positivos.
De acordo com o padrão C, a assinatura de Plain Char é "implementação definida".
Em geral, os implementadores escolheram o que era mais eficiente para implementar em sua arquitetura. No X86 Systems, o char é geralmente assinado. Nos sistemas de braço, geralmente não é assinado (a Apple iOS é uma exceção).
De acordo com "The C ++ Programming Language", de Bjarne Stroustrup, char
é "implementação definida". Pode ser signed char
ou unsigned char
dependendo da implementação. Você pode verificar se char
é assinado ou não usando std::numeric_limits<char>::is_signed
.
Agora, sabemos que o padrão deixa isso até a implementação.
Mas como verificar um tipo é signed
ou unsigned
, como char
?
Eu escrevi uma macro para fazer isso:
#define IS_UNSIGNED(t) ((t)~1 > 0)
e teste com gcc
, clang
, e cl
. Mas não tenho certeza se é sempre seguro para outros casos.