2012-09-30 91 views
13

En this answer y los comentarios adjuntos, Pavel Minaev hace que el siguiente argumento de que, en C, los únicos tipos a los que uint8_t puede typedef'd son char y unsigned char. Estoy mirando this draft del estándar C.¿Puede uint8_t ser un tipo sin carácter?

  • La presencia de uint8_t implica la presencia de un tipo correspondiente int8_t (7.18.1p1).
  • int8_t tiene 8 bits de ancho y no tiene bits de relleno (7.18.1.1p1).
  • Los tipos correspondientes tienen el mismo ancho (6.2.5p6), por lo que uint8_t también tiene 8 bits de ancho.
  • unsigned char es CHAR_BIT bits de ancho (5.2.4.2.1p2 y 6.2.6.1p3).
  • CHAR_BIT es al menos 8 (5.2.4.2.1p1).
  • CHAR_BIT es como máximo 8, ya sea porque uint8_t es unsigned char, o que es un no unsigned char, tipo no campo de bits cuya anchura es un múltiplo de CHAR_BIT (6.2.6.1p4).

Basado en este argumento, de acuerdo en que, si uint8_t existe, entonces tanto ella como unsigned char tiene representaciones idénticos: 8 bits de valor y 0 bits de relleno. Eso no parece obligarlos a ser del mismo tipo (por ejemplo, 6.2.5p14).

¿Se permite que uint8_t se typedef'd a un tipo extendido entero sin signo (6.2.5p6) con la misma representación que unsigned char? Sin duda debe ser typedef'd (7.18.1.1p2), y no puede ser cualquier tipo de entero estándar sin signo que no sea unsigned char (o char si no está firmado). Este tipo extendido hipotético no sería un tipo de carácter (6.2.5p15) y, por lo tanto, no calificaría para el acceso con alias a un objeto de un tipo incompatible (6.5p7), lo cual me parece la razón por la que un compilador quisiera hacerlo. cosa.

+0

una respuesta a su pregunta explícita, pero es posible que CHAR 'es un tipo sin signo, luego' uint8_t' podría ser typedef'ed a 'char' en lugar de' u nsigned char'. –

+0

En un momento (hace varios años) hubo una discusión seria dentro del proyecto GCC de agregar un tipo de entero extendido con exactamente las propiedades que está describiendo --- ocho bits de ancho, no un tipo de carácter, y no siendo un caso especial en tipo basado en alias basado en análisis, pero hasta donde yo sé, nunca fue a ninguna parte, y no hubo ninguna sugerencia de que sea el tipo subyacente para 'uint8_t' (posiblemente porque nadie pensó en eso en ese momento). – zwol

+0

Tenga en cuenta que 'uint8_t' no necesita existir en absoluto. Solo está definido condicionalmente. –

Respuesta

-1

int8_t y uint8_t se diferencian solo por REPRESENTACIÓN y NO por el contenido (bits). int8_t usa 7 bits más bajos para los datos y el 8º bit representa "signo" (positivo o negativo). Por lo tanto, el rango de int8_t es de -128 a +127 (0 se considera un valor positivo).

uint8_t también tiene 8 bits de ancho, PERO los datos que contiene son SIEMPRE positivos. Por lo tanto, el rango de uint8_t es de 0 a 255.

Teniendo en cuenta este hecho, char tiene 8 bits de ancho. char sin signo también sería de 8 bits de ancho, pero sin el "signo". Del mismo modo corto y sin signo corto son ambos de 16 bits de ancho.

SI, sin embargo, "unsigned int" tiene 8 bits de ancho, entonces ... ya que C no es demasiado nazi, se permite. ¿Y por qué un escritor de compiladores permitiría tal cosa? ¡LEGIBILIDAD!

+1

El ancho de 'unsigned int' no es menor que 16. – user1710520

+0

según las especificaciones YES. Pero estamos viendo esto hipotéticamente, ¿no? –

+1

Hipotéticamente, pero conforme a los estándares. –

4

Si existe uint8_t, el requisito de no-padding implica que CHAR_BIT es 8. Sin embargo, no hay ninguna razón fundamental que puedo encontrar qué uint8_t no puede ser definido con un tipo de número entero extendida. Además, no hay garantía de que las representaciones sean las mismas; por ejemplo, los bits podrían interpretarse en el orden opuesto.

Si bien esto parece tonto y gratuito para uint8_t, podría tener mucho sentido para int8_t. Si una máquina usa nativamente el complemento o el signo/magnitud, entonces signed char no es adecuado para int8_t. Sin embargo, podría usar un tipo entero con signo extendido que emule el complemento de dos para proporcionar int8_t.

+0

"por ejemplo, los bits podrían interpretarse en el orden opuesto". ¿Eso implica que los bits se pueden interpretar en el orden opuesto en 'unsigned char' vs (cada byte individual de)' unsigned int'? ¿O solo son los tipos de enteros extendidos los que pueden cruzar el bus de datos ;-) –

+0

@SteveJessop: 'unsigned int' es típicamente N bytes (donde N es típicamente 4) interpretado en cualquier orden endian o big endian, pero el estándar no dice nada sobre el orden de los bytes o incluso los bits. No estoy seguro de si su pregunta "cruzar el bus de datos" fue seria, pero no hay ninguna razón para que '* (char sin signo *) & (uint8_t) {1}' tenga que ser 1 y no otra potencia de dos . (El requisito de "binario puro" significa que es * algún * poder de dos, sin embargo). –

+1

No quise decir en serio que se lograría cruzando físicamente el autobús, pero aparte de eso, la pregunta era seria. Es solo que no creo que haya considerado antes que 'unsigned int a = 1; for (unsigned char * p = (unsigned char *) & a; p <(unsigned char *) (&a+1); ++ p) if (* p == 1) return; 'no necesita regresar. Del mismo modo, supongo que algo tonto como' unsigned int a = 0xF; strlen ((char *) &a); 'es un posible desbordamiento del búfer proporcionado' sizeof (a)> = 4' (4 es el número de bits establecidos en el valor), a menos que el estándar indique que los bytes de el objeto repr. son * bits de valor contiguos * –

2

En 6.3.1.1 (1) (del proyecto de N1570 de la norma C11), podemos leer

El rango de cualquier tipo entero norma deberá ser mayor que el rango de cualquier tipo entero extendida con el mismo ancho

Por lo tanto, el estándar explícitamente permite la presencia de tipos enteros extendidos del mismo ancho que un tipo entero estándar.

No hay nada en la norma que prohíbe un

typedef implementation_defined_extended_8_bit-unsigned_integer_type uint8_t; 

si ese tipo entero extendida coincide con las especificaciones para uint8_t (no hay bits de relleno, anchura de 8 bits), por lo que yo puedo ver.

Así que sí, si la aplicación proporciona un tipo entero tan prolongado, uint8_t puede ser typedef'ed a eso.

0

uint8_t pueden existir y ser un tipo distinto de unsigned char.

Una implicación importante de esto es en la resolución de sobrecarga; es dependiente de la plataforma si:

uint8_t by = 0; 
std::cout << by; 

utiliza

  1. operator<<(ostream, char)
  2. operator<<(ostream, unsigned char) o
  3. operator<<(ostream, int)
No
+0

Esta es una pregunta en C. Tendría que proporcionar referencias de C++ para todo lo que OP citó para respaldar su reclamo –

+0

¿Quiso decir que '' uint8_t' puede existir y ser un tipo distinto tanto de 'char' como' unsigned char' "? O solo afirma que puede ser distinto de' unsigned char' debido al caso donde es 'char'? Además, ¿por qué estoy recibiendo deja vu escribiendo esto –

Cuestiones relacionadas