¿Hay máquinas donde sizeof (char)! = 1, o al menos CHAR_BIT> 8?

93

¿Hay máquinas (o compiladores), dónde sizeof(char) != 1?

¿El estándar C99 dice que la sizeof(char)implementación del cumplimiento del estándar DEBE ser exactamente 1? Si es así, por favor, deme el número de sección y la cita.

Actualización: si tengo una máquina (CPU), que no puede direccionar bytes (la lectura mínima es 4 bytes, alineados), pero solo 4-s de bytes ( uint32_t), ¿ puede el compilador para esta máquina definir sizeof(char)en 4? sizeof(char)será 1, pero char tendrá 32 bits ( CHAR_BITmacros)

Actualización 2: ¡ Pero el tamaño del resultado NO es un BYTES! es del tamaño de CHAR. ¿Y char puede ser de 2 bytes o (puede ser) de 7 bits?

Update3: Ok. Todas las máquinas tienen sizeof(char) == 1. Pero, ¿qué máquinas tienen CHAR_BIT > 8?

osgx
fuente
4
Me preocupa el cumplimiento del estándar C99. Trabajo en estrecha colaboración con compiladores de C99
osgx
2
A medida que Unicode se vuelve aún más importante, pueden aparecer compiladores no estándar que usen caracteres Unicode como char(en lugar de wchar). Incluso si el estándar dice que sizeof(char)debe ser 1, no confiaría en esa suposición.
Chip Uni
14
no hay compiladores de C donde sizeof (char) no es 1, Unicode o no.
nos
6
@Chip: sizeof(char)es siempre 1, incluso si char es de 32 bits (como sucede en algunos sistemas). C tiene muchas verrugas divertidas.
Nick Bastin
2
Todas las versiones del estándar C requieren que CHAR_BIT sea al menos 8; no puede tener CHAR_BIT == 7 y cumplir con los estándares. Sin embargo, es perfectamente factible que las máquinas tengan CHAR_BIT> 8. Las viejas máquinas Cray lo tenían, creo ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)en esas; no recuerdo sizeof(int) == sizeof(long)si CHAR_BIT era 32 o 64; supongo que era 32, y creo que sizeof(long) == 1también. (Puede encontrar una referencia, pero no acceso en línea a, un manual de Cray C ).
Jonathan Leffler

Respuestas:

91

Siempre es uno en C99, sección 6.5.3.4:

Cuando se aplica a un operando que tiene el tipo char, unsigned char o firmado char, (o una versión calificada del mismo) el resultado es 1.

Editar: no es parte de su pregunta, pero sí el interés de Harbison y Steele, 3ª ed. (pre c99) pág. 148:

Una unidad de almacenamiento se considera la cantidad de almacenamiento ocupada por un carácter; el tamaño de un objeto de tipo chares por tanto 1.

Editar: En respuesta a su pregunta actualizada, la siguiente pregunta y respuesta de Harbison y Steele es relevante (ibid, Ex.4 del Cap.6):

¿Está permitido tener una implementación de C en la que el tipo charpuede representar valores que van desde -2,147,483,648 hasta 2,147,483,647? Si es así, ¿qué estaría sizeof(char) bajo esa implementación? ¿Cuáles serían los rangos de tipo más pequeños y más grandes int?

Respuesta (ibid, p. 382):

Está permitido (si es un desperdicio) que una implementación utilice 32 bits para representar el tipo char. Independientemente de la implementación, el valor de sizeof(char)siempre es 1.

Si bien esto no aborda específicamente un caso en el que, digamos, los bytes son 8 bits y charson 4 de esos bytes (realmente imposible con la definición de c99, ver más abajo), el hecho de que sizeof(char) = 1siempre queda claro en el estándar c99 y Harbison y Steele.

Editar: De hecho (esto es en respuesta a su pregunta upd 2), en lo que respecta a c99 sizeof(char) está en bytes, de la sección 6.5.3.4 nuevamente:

El operador sizeof produce el tamaño (en bytes) de su operando

así que combinado con la cita anterior, bytes de 8 bits y charcomo 4 de esos bytes es imposible: para c99 un byte es lo mismo que a char.

En respuesta a su mención de la posibilidad de un 7 bit char: esto no es posible en c99. Según el apartado 5.2.4.2.1 de la norma el mínimo es 8:

Sus valores definidos por la implementación serán iguales o mayores [énfasis mío] en magnitud a los mostrados, con el mismo signo.

- número de bits para el objeto más pequeño que no es un campo de bits (byte)

 **CHAR_BIT 8**

- valor mínimo para un objeto de tipo char firmado

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

- valor máximo para un objeto de tipo carácter firmado

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

- valor máximo para un objeto de tipo unsigned char

**UCHAR_MAX 255//28−1** 

- valor mínimo para un objeto de tipo char

**CHAR_MIN**    see below 

- valor máximo para un objeto de tipo char

**CHAR_MAX**    see below

[...]

Si el valor de un objeto de tipo char se trata como un entero con signo cuando se utiliza en una expresión, el valor de CHAR_MIN será el mismo que el de SCHAR_MIN y el valor de CHAR_MAX será el mismo que el de SCHAR_MAX. De lo contrario, el valor de CHAR_MIN será 0 y el valor de CHAR_MAX será el mismo que el de UCHAR_MAX. El valor UCHAR_MAX será igual a 2 ^ CHAR_BIT - 1.

Ramashalanka
fuente
9
Nota adicional. hay una macro CHAR_BITS que le dirá cuántos bits son sus caracteres.
nos
1
Los datos completos de este gran libro son de Harbison y Steele. C: A Reference Manual, Third Edition, Prentice Hall, 1991
osgx
2
Si sabe que está trabajando con tipos de caracteres y sabe que el lenguaje requiere que tengan un tamaño de 1, ¿por qué es una buena idea poner siempre el tamaño redundante de (char)?
1
(a) y (c) tienen ramificaciones mucho más serias que no se puede esperar resolver, o ni siquiera acercarse a resolver; también YAGNI. Alguien como en (b) solo necesita que le digan una vez --- no necesito enseñarles en cada línea de mi código. Sin embargo, existen inconvenientes en su uso sizeof(char): es otro elemento para debatir / verificar / etc. en sus convenciones / estándares / pautas de codificación, pierdo el tiempo preguntándome si realmente conoce C y qué más puede ser incorrecto, ocupa el "ancho de banda" visual / mental / de línea de texto.
1
@Ramashalanka: Sí, el código compilado es equivalente. Son todos los problemas relacionados con la legibilidad y, de lo contrario, cómo la gente usa el código fuente del que estoy hablando. (Y FWIW, creo que tienes una respuesta +1 decente aquí, creo que "siempre usar sizeof (char)" es un error y un problema de botón de acceso rápido para mí, incluso si es un problema pequeño.)
21

No hay máquinas donde sizeof(char)es 4. Siempre es 1 byte. Ese byte puede contener 32 bits, pero en lo que respecta al compilador de C, es un byte. Para obtener más detalles, voy a señalarle la pregunta frecuente 26.6 de C ++ . Ese enlace lo cubre bastante bien y estoy bastante seguro de que C ++ obtuvo todas esas reglas de C. También puede consultar comp.lang.c FAQ 8.10 para caracteres de más de 8 bits.

Upd2: ¡Pero el tamaño del resultado NO es un BYTES! es del tamaño de CHAR. ¿Y char puede ser de 2 bytes o (puede ser) de 7 bits?

Sí, son bytes. Déjame decirlo otra vez. sizeof(char)es de 1 byte según el compilador de C. Lo que la gente llama coloquialmente un byte (8 bits) no es necesariamente lo mismo que lo que el compilador de C llama un byte. La cantidad de bits en un byte C varía según la arquitectura de su máquina. También se garantiza que sea al menos 8.

Michael Kristofik
fuente
3
¡¡¡Por favor!!! C ++ es el lenguaje realmente DIFERENTE de C (C99). Esta pregunta es solo sobre C simple.
osgx
<strike> ¿Qué puedo hacer cuando la máquina / CPU no puede acceder a bytes de 8 bits? El acceso no alineado está prohibido. </strike> (Incluso en x86, malloc devuelve datos alineados y asigna memoria en multiplicaciones de 4 bytes). <strike> Entonces CHAT_BIT será mayor que 8. Sí, tal plataforma puede ser bastante especial. </ Strike >
osgx
10
@osgx, tiendo a gritar tanto como tú cuando la gente intenta mezclar C y C ++. Pero creo que, en este caso, una entrada de preguntas frecuentes de C ++ se aplica igualmente bien a C.
Michael Kristofik
3
El nombre correcto para "8 bits" es octeto. El estándar C utiliza la palabra "byte" para un objeto del tamaño de un carácter. Otros pueden usar la palabra "byte" de diferentes maneras, a menudo cuando significan "octeto", pero en C (y C ++, o Objective-C) significa "objeto del tamaño de un carácter". Un carácter puede tener más de 8 bits o más de un octeto, pero siempre es un byte.
gnasher729
9

PDP-10 y PDP-11 fue.

Actualización: no hay compiladores C99 para PDP-10.

Algunos modelos de DSP SHARC de 32 bits de Analog Devices tienen CHAR_BIT = 32, y el DSP de Texas Instruments de TMS32F28xx tiene CHAR_BIT = 16, según se informa .

Actualización: hay GCC 3.2 para PDP-10 con CHAR_BIT = 9 (verifique include / limits.h en ese archivo).

osgx
fuente
1
No confunda las implementaciones de lenguajes similares pero no C con C. Incluso dijo "Estoy preocupado por el cumplimiento del estándar C99. Trabajo en estrecha colaboración con los compiladores C99".
2
@Roger: No es justo llamar a GCC3 no compatible con C99 a menos que se trate de casos extremos extremos que se consideran errores en GCC.
Joshua
1
@ Joshua, creo que Roger dice acerca de los compiladores históricos de K&R y pcc. Tampoco es justo afirmar que cumple con C99 antes de que se ejecute el conjunto de pruebas de cumplimiento de C99 en PDP-10, cuando se compila con este puerto (puede haber errores de portar y de la propia máquina). Pero se puede esperar que esté cerca del estándar C99 al igual que GCC3.2 en x86.
osgx
1
@Joshua: Se permite que CHAR_BIT, en C99, sea mayor que 8, pero sizeof (char) aún debe ser 1 (y esta respuesta era muy diferente cuando dejé ese comentario). No voy a llamar a GCC3 no compatible, y C89 hace el mismo requisito aquí, por cierto. Cité ese texto para decir que osgx es el que se preocupa por el cumplimiento de C99 y usa compiladores de C99, entonces, ¿
2
Autor de PDP-10 GCC aquí. CHAR_BIT es 9, pero el tamaño de (char) sigue siendo 1.
Lars Brinkhoff