Existem máquinas, onde sizeof (char)! = 1, ou pelo menos CHAR_BIT> 8?

93

Existem máquinas (ou compiladores), onde sizeof(char) != 1?

O padrão C99 diz que sizeof(char)a implementação de conformidade com o padrão DEVE ser exatamente 1? Em caso afirmativo, por favor, me dê o número da seção e citação.

Atualização: Se eu tiver uma máquina (CPU), que não pode endereçar bytes (leitura mínima é 4 bytes, alinhados), mas apenas 4-s de bytes ( uint32_t), o compilador para esta máquina pode definir sizeof(char)para 4? sizeof(char)será 1, mas char terá 32 bits ( CHAR_BITmacros)

Update2: Mas o resultado sizeof NÃO é um BYTES! é do tamanho de CHAR. E char pode ter 2 bytes ou (pode ser) 7 bits?

Update3: Ok. Todas as máquinas têm sizeof(char) == 1. Mas quais máquinas têm CHAR_BIT > 8?

osgx
fonte
4
Estou preocupado com a conformidade com o padrão C99. Trabalho em estreita colaboração com compiladores C99
osgx
2
À medida que o Unicode se torna ainda mais importante, podem surgir compiladores não padrão que usam caracteres Unicode como char(em vez de wchar.) Mesmo se o padrão disser que sizeof(char)deve ser 1, eu não confiaria nessa suposição.
Chip Uni
14
não há compiladores C onde sizeof (char) não é 1, unicode ou não.
nos
6
@Chip: sizeof(char)é sempre 1, mesmo que char seja de 32 bits (como acontece em alguns sistemas). C tem muitas verrugas divertidas.
Nick Bastin
2
Todas as versões do padrão C requerem que CHAR_BIT seja pelo menos 8; você não pode ter CHAR_BIT == 7 e ser compatível com o padrão. No entanto, é perfeitamente viável que as máquinas tenham CHAR_BIT> 8. As máquinas Cray antigas tinham, eu acredito ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)nessas; não me lembro sizeof(int) == sizeof(long)se CHAR_BIT tinha 32 ou 64; acho que era 32, e acho que sizeof(long) == 1também. (Você pode encontrar uma referência, mas não o acesso online a, um manual do Cray C. )
Jonathan Leffler

Respostas:

91

É sempre um em C99, seção 6.5.3.4:

Quando aplicado a um operando que tem tipo char, unsigned char, ou signed char, (ou uma versão qualificada disso) o resultado é 1.

Edit: não faz parte da sua pergunta, mas pelo interesse de Harbison e Steele, 3ª ed. (antes de 99) p. 148:

Uma unidade de armazenamento é considerada a quantidade de armazenamento ocupada por um personagem; o tamanho de um objeto de tipo charé, portanto, 1.

Edit: Em resposta à sua pergunta atualizada, a seguinte pergunta e resposta de Harbison e Steele são relevantes (ibid, Ex. 4 do Cap. 6):

É permitido ter uma implementação C em que tipo charpode representar valores que variam de -2.147.483.648 a 2.147.483.647? Em caso afirmativo, o que estaria sizeof(char) sob essa implementação? Quais seriam os menores e maiores intervalos de tipo int?

Resposta (ibid, p. 382):

É permitido (se desperdício) para uma implementação usar 32 bits para representar o tipo char. Independentemente da implementação, o valor de sizeof(char)é sempre 1.

Embora isso não trate especificamente de um caso em que, digamos, os bytes tenham 8 bits e charsejam 4 desses bytes (na verdade, impossível com a definição c99, veja abaixo), o fato de que sizeof(char) = 1sempre fica claro no padrão c99 e em Harbison e Steele.

Edit: Na verdade (isso é em resposta à sua pergunta sobre o Upd 2), no que diz respeito a c99 sizeof(char) está em bytes, da seção 6.5.3.4 novamente:

O operador sizeof produz o tamanho (em bytes) de seu operando

então combinado com a citação acima, bytes de 8 bits e char4 desses bytes é impossível: para c99 um byte é o mesmo que a char.

Em resposta à sua menção à possibilidade de 7 bits char: isso não é possível em c99. De acordo com a seção 5.2.4.2.1 da norma, o mínimo é 8:

Seus valores definidos pela implementação devem ser iguais ou maiores [grifo meu] em magnitude aos mostrados, com o mesmo sinal.

- número de bits para o menor objeto que não é um campo de bits (byte)

 **CHAR_BIT 8**

- valor mínimo para um objeto do tipo char assinado

**SCHAR_MIN -127//−(27−1)** 

- valor máximo para um objeto do tipo char assinado

**SCHAR_MAX +127//27−1** 

- valor máximo para um objeto do tipo unsigned char

**UCHAR_MAX 255//28−1** 

- valor mínimo para um objeto do tipo char

**CHAR_MIN**    see below 

- valor máximo para um objeto do tipo char

**CHAR_MAX**    see below

[...]

Se o valor de um objeto do tipo char for tratado como um inteiro com sinal quando usado em uma expressão, o valor de CHAR_MIN deve ser o mesmo de SCHAR_MIN e o valor de CHAR_MAX deve ser o mesmo de SCHAR_MAX. Caso contrário, o valor de CHAR_MIN deve ser 0 e o valor de CHAR_MAX deve ser o mesmo de UCHAR_MAX. O valor UCHAR_MAX deve ser igual a 2 ^ CHAR_BIT - 1.

Ramashalanka
fonte
9
Nota adicional. há uma macro CHAR_BITS que vai te dizer quantos bits são seus chars.
nos
1
Os dados completos deste grande livro são de Harbison e Steele. C: Um Manual de Referência, Terceira Edição, Prentice Hall, 1991
osgx
2
Se você sabe que está trabalhando com tipos de char e sabe que a linguagem exige que eles tenham o tamanho 1, por que é uma boa ideia sempre colocar o tamanho redundante de (char)?
1
(a) e (c) têm ramificações muito mais sérias que não podemos esperar resolver, ou mesmo chegar perto de resolver; também YAGNI. Alguém como em (b) só precisa ser informado uma vez - não preciso ensiná-los em todas as linhas do meu código. No entanto, existem desvantagens em usar sizeof(char): é outro item para debater / verificar / etc. em suas convenções / padrões / diretrizes de codificação, perco meu tempo imaginando se você realmente conhece C e o que mais pode estar incorreto, ocupa "largura de banda" visual / mental / linha de texto.
1
@Ramashalanka: Sim, o código compilado é equivalente. São todos os problemas em torno da legibilidade e de como as pessoas usam o código-fonte de que estou falando. (E FWIW, acho que você tem uma resposta +1 decente aqui, apenas acho que "sempre use sizeof (char)" é um erro e um problema de botão de atalho para mim, mesmo que seja um pequeno problema.)
21

Não há máquinas onde sizeof(char)é 4. É sempre 1 byte. Esse byte pode conter 32 bits, mas no que diz respeito ao compilador C, é um byte. Para obter mais detalhes, na verdade vou apontar para C ++ FAQ 26.6 . Esse link o cobre muito bem e estou quase certo de que C ++ obteve todas essas regras de C. Você também pode consultar comp.lang.c FAQ 8.10 para caracteres maiores que 8 bits.

Upd2: Mas o resultado sizeof NÃO é um BYTES! é do tamanho de CHAR. E char pode ter 2 bytes ou (pode ser) 7 bits?

Sim, são bytes. Deixe-me dizer isso novamente. sizeof(char)é 1 byte de acordo com o compilador C. O que as pessoas chamam coloquialmente de byte (8 bits) não é necessariamente o mesmo que o compilador C chama de byte. O número de bits em um byte C varia dependendo da arquitetura de sua máquina. Também é garantido que seja pelo menos 8.

Michael Kristofik
fonte
3
Por favor!!! C ++ é a linguagem realmente DIFERENTE do C (C99). Esta pergunta é apenas sobre C simples.
osgx
<strike> O que posso fazer quando a máquina / CPU não consegue acessar bytes de 8 bits? O acesso desalinhado é proibido. </strike> (Mesmo em x86, malloc retorna dados alinhados e aloca memória em multiplicações de 4 bytes.) <strike> Então CHAT_BIT será maior que 8. Sim, essa plataforma pode ser bastante especial. </ Strike >
osgx
10
@osgx, eu tendo a gritar tanto quanto você acabou de gritar quando as pessoas tentam misturar C e C ++. Mas acho que , neste caso, uma entrada de FAQ do C ++ se aplica igualmente bem a C.
Michael Kristofik
3
O nome correto para "8 bits" é octeto. O padrão C usa a palavra "byte" para um objeto do tamanho de um caractere. Outros podem usar a palavra "byte" de maneiras diferentes, geralmente quando significam "octeto", mas em C (e C ++ ou Objective-C) significa "objeto do tamanho de um caractere". Um char pode ter mais de 8 bits ou mais de um octeto, mas é sempre um byte.
gnasher729
9

PDP-10 e PDP-11 eram.

Atualização: não há compiladores C99 para PDP-10.

Alguns modelos de Analog Devices de 32 bits SHARC DSP têm CHAR_BIT = 32, e Texas Instruments DSP de TMS32F28xx tem CHAR_BIT = 16, supostamente .

Atualização: Existe GCC 3.2 para PDP-10 com CHAR_BIT = 9 (verifique include / limits.h nesse arquivo).

osgx
fonte
1
Não confunda implementações de linguagens semelhantes, mas não C, com C. Você até disse "Estou preocupado com a conformidade com o padrão C99. Trabalho em estreita colaboração com compiladores C99".
2
@Roger: Não é justo chamar o GCC3 de não compatível com o C99, a menos que você esteja lidando com casos extremos que são considerados bugs no GCC.
Joshua
1
@Joshua, acho que Roger fala sobre K&R e compiladores históricos pcc. Também não é justo alegar que é compatível com C99 antes que o pacote de teste de conformidade com C99 seja executado no PDP-10, quando compilado com esta porta (pode haver bugs de portabilidade e da própria máquina). Mas pode-se esperar que esteja próximo do padrão C99, assim como GCC3.2 em x86.
osgx
1
@Joshua: CHAR_BIT é permitido, em C99, ser maior que 8, mas sizeof (char) ainda deve ser 1 (e essa resposta foi muito diferente quando deixei esse comentário). Não estou chamando GCC3 de não compatível, e C89 faz o mesmo requisito aqui, BTW. Citei esse texto para dizer que osgx é quem está preocupado com a compatibilidade C99 e usa compiladores C99, então por que ele está preocupado com compiladores não C99?
2
Autor do PDP-10 GCC aqui. CHAR_BIT é 9, mas sizeof (char) ainda é 1.
Lars Brinkhoff