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

10 minutos de lectura

avatar de usuario
osgx

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

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

Actualizar:
Si tengo una máquina (CPU), que no puede direccionar bytes (la lectura mínima es de 4 bytes, alineados), pero solo 4 s de bytes (uint32_t), puede compilador para esta máquina definir sizeof(char) ¿para 4? sizeof(char) será 1, pero char tendrá 32 bits (CHAR_BIT macros)

Actualización2:
¡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?

Actualización3:
Está bien. Todas las máquinas tienen sizeof(char) == 1. Pero que maquinas tienen CHAR_BIT > 8 ?

  • Estoy preocupado por el cumplimiento del estándar C99. Trabajo en estrecha colaboración con los compiladores C99.

    – osgx

    7 de febrero de 2010 a las 1:06


  • A medida que Unicode se vuelve aún más importante, es posible que surjan compiladores no estándar que usen caracteres Unicode como char (en vez de wchar.) Incluso si la norma dice que sizeof(char) debe ser 1, no confiaría en esa suposición.

    – Chip Uni

    7 de febrero de 2010 a las 1:17

  • no hay compiladores de C donde sizeof(char) no sea 1, Unicode o no.

    – nos

    7 de febrero de 2010 a las 1:47

  • @Chip: sizeof(char) siempre es 1, incluso si char es de 32 bits (como sucede en algunos sistemas). C tiene muchas verrugas divertidas.

    –Nick Bastin

    1 de julio de 2010 a las 22:15

  • 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. Creo que las viejas máquinas Cray tenían (sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int) sobre estos; no recuerdo si sizeof(int) == sizeof(long) o si CHAR_BIT era 32 o 64; Esperaba que fueran 32, y creo sizeof(long) == 1 también. (Puede encontrar una referencia a, pero no acceso en línea a, un cray c manual).

    –Jonathan Leffler

    2 de diciembre de 2013 a las 0:41

avatar de usuario
Ramashalanka

Siempre es uno en C99, sección 6.5.3.4:

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

Editar: no es parte de su pregunta, sino el interés de Harbison y Steele. C: Manual de referencia, tercera edición, Prentice Hall, 1991 (antes de c99) p. 148:

Se considera que una unidad de almacenamiento es la cantidad de almacenamiento que ocupa un personaje; el tamaño de un objeto de tipo char es, por lo tanto 1.

Editar: en respuesta a su pregunta actualizada, la siguiente pregunta y respuesta de Harbison y Steele son relevantes (ibid, Ex. 4 de Ch. 6):

¿Es permisible tener una implementación C en la que tipo char puede representar valores que van desde -2,147,483,648 hasta 2,147,483,647? si es asi cual seria sizeof(char)
bajo esa implementación? ¿Cuáles serían los rangos de tipo más pequeño y más grande? int?

Respuesta (ibíd., pág. 382):

Está permitido (si es un desperdicio) que una implementación use 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, por ejemplo, los bytes son de 8 bits y char son 4 de esos bytes (en realidad imposible con la definición c99, ver más abajo), el hecho de que sizeof(char) = 1 siempre está claro desde 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) es en bytes, de la sección 6.5.3.4 nuevamente:

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

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

En respuesta a su mención de la posibilidad de un 7 bits 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 mayor [my emphasis] en magnitud a las mostradas, 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 signed char

SCHAR_MIN -127

— valor máximo para un objeto de tipo signed char

SCHAR_MAX +127

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

UCHAR_MAX 255

— valor mínimo para un objeto de tipo char

CHAR_MIN vea abajo

— valor máximo para un objeto de tipo char

CHAR_MAX vea abajo

[…]

Si el valor de un objeto de tipo char
se trata como un entero con signo cuando se usa 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 2CHAR_BIT − 1.

  • Si sabe que está trabajando con tipos char y sabe que el idioma requiere que tengan un tamaño de 1, ¿por qué es una buena idea poner siempre el tamaño redundante de (char)?

    Roger Paté

    7 de febrero de 2010 a las 3:58

  • @Roger. En general, por supuesto, es muy importante utilizar sizeof para la implementación de la independencia. Sí, teniendo en cuenta todo lo anterior, char es un poco una excepción, y es seguro asumir sizeof(char)=1. Dije “buena idea” porque: (a) si alguien más tarde cambia de uso, por ejemplo, longreduce la posibilidad de error, ya que sizeof(char) sirve como recordatorio, (b) un lector de código, como el OP, que no está seguro acerca de sizeof(char), no pierde el tiempo preocupándose si el código es correcto, (c) implementaciones actuales no estándar o futuras (improbables). Esa es la razón de mi hábito, de todos modos.

    – Ramashalanka

    7 de febrero de 2010 a las 4:40

  • (a) y (c) tienen ramificaciones mucho más serias que esto no puede esperar resolver, o incluso estar cerca de resolver; también YAGNI. Alguien como en (b) solo necesita que se le diga una vez — No necesito enseñarles en cada línea de mi código. Sin embargo, hay inconvenientes en el uso sizeof(char): es otro elemento a debatir/verificar/etc. en sus convenciones/estándares/directrices de codificación, me hace perder el tiempo preguntándome si realmente sabe C y qué más puede ser incorrecto, ocupa el “ancho de banda” visual/mental/de línea de texto.

    Roger Paté

    7 de febrero de 2010 a las 4:46


  • @Ramashalanka: Sí, el código compilado es equivalente. Son todos los problemas relacionados con la legibilidad y, de lo contrario, cómo las personas usan el código fuente de lo que estoy hablando. (Y FWIW, creo que tiene una respuesta decente de +1 aquí, solo encuentro que “siempre usar tamaño de (char)” está equivocado y es un tema candente para mí, incluso si es un problema pequeño).

    Roger Paté

    8 de febrero de 2010 a las 8:18


  • @Ramashalanka: Aunque supongo que es algo subjetivo. Está bien si algunas personas realmente quieren usarlo, para ser coherentes con su uso el resto del tiempo. Sin embargo, en mi opinión, no tiene sentido, ya que si no puedes confiar en eso sizeof(char) == 1 permanecerá igual, realmente no puedes confiar en nada.

    – mk12

    9 de agosto de 2012 a las 0:08

avatar de usuario
Michael Kristofik

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 más detalles, en realidad voy a señalarte en el Preguntas frecuentes sobre C++ 26.6. 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 Preguntas frecuentes 8.10 para caracteres mayores 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.

  • ¡¡¡Por favor!!! C++ es el lenguaje realmente DIFERENTE de C (C99). Esta pregunta es solo sobre C simple.

    – osgx

    7 de febrero de 2010 a las 2:04


  • ¿Qué puedo hacer cuando la máquina/CPU no puede acceder a los bytes de 8 bits? El acceso sin alinear está prohibido. (Incluso en x86 malloc devuelve datos alineados y asigna memoria en múltiplos de 4 bytes). Entonces CHAT_BIT será mayor que 8. Sí, esa plataforma puede ser bastante especial.

    – osgx

    7 de febrero de 2010 a las 2:09


  • @osgx, tiendo a gritar tanto como tú cuando las personas intentan mezclar C y C++. Pero yo pienso en este caso esa entrada de preguntas frecuentes de C ++ se aplica igualmente bien a C.

    – Michael Kristofik

    7 de febrero de 2010 a las 2:35

  • El nombre correcto para “8 bits” es octeto. El estándar C usa la palabra “byte” para un objeto que tiene el tamaño de un char. Otros pueden usar la palabra “byte” de diferentes maneras, a menudo cuando quieren decir “octeto”, pero en C (y C ++ u 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

    11 de abril de 2014 a las 14:09

avatar de usuario
osgx

PDP-10 y PDP-11 era.

Actualizar: no hay compiladores C99 para PDP-10.

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

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

  • 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”.

    Roger Paté

    7 de febrero de 2010 a las 4:01

  • @Roger: No es justo decir que GCC3 no cumple con C99 a menos que se trate de casos extremos que se consideran errores en GCC.

    – Josué

    7 de febrero de 2010 a las 4:39


  • @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 portabilidad 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

    7 de febrero de 2010 a las 4:42


  • @Joshua: se permite que CHAR_BIT, en C99, sea mayor que 8, pero el tamaño de (char) aún debe ser 1 (y esta respuesta fue muy diferente cuando dejé ese comentario). No estoy llamando a GCC3 no compatible, y C89 hace el mismo requisito aquí, por cierto. Cité ese texto para decir que osgx es el que está preocupado por el cumplimiento de C99 y usa compiladores C99, así que ¿Por qué le preocupan los compiladores que no son C99?

    Roger paté

    7 de febrero de 2010 a las 4:55

  • Autor de PDP-10 GCC aquí. CHAR_BIT es 9, pero sizeof(char) sigue siendo 1.

    -Lars Brinkhoff

    3 de noviembre de 2016 a las 8:01


Lo que usted llama “bytes” se conoce mejor como “octetos”. En C, “bytes” y “chars” significan exactamente lo mismo: la unidad de memoria más pequeña.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad