tipos tipo sirve rangos que programacion para long lenguaje derivados declaracion datos dato c++ c++11 language-lawyer

c++ - tipo - unsigned char c



Establecer todos los bytes de int a(unsigned char) 0, garantizado para representar cero? (4)

C ++ 11

Creo que la parte pertinente es

3.9.1 / 1 en C ++ 11

Para los tipos de caracteres, todos los bits de la representación del objeto participan en la representación del valor. Para los tipos de caracteres sin signo, todos los patrones de bits posibles de la representación del valor representan números. Estos requisitos no son válidos para otros tipos.

Junto con 3.9.1 / 7

Las representaciones de tipos integrales definirán valores mediante el uso de un sistema de numeración binario puro.

C11

6.2.6.2 es muy explícito

Para los tipos enteros sin signo que no sean char sin signo, los bits de la representación del objeto se dividirán en dos grupos: bits de valor y bits de relleno (no es necesario que exista ninguno de estos últimos). Si hay N bits de valor, cada bit representará una potencia diferente de 2 entre 1 y 2 N-1 , de modo que los objetos de ese tipo sean capaces de representar valores de 0 a 2 N - 1 utilizando una representación binaria pura; esto se conocerá como la representación del valor. Los valores de los bits de relleno no están especificados.

Para los tipos enteros con signo, los bits de la representación del objeto se dividirán en tres grupos: bits de valor, bits de relleno y el bit de signo. No es necesario que haya ningún relleno; el signo firmado no debe contener ningún relleno. Habrá exactamente un bit de signo. Cada bit que sea un bit de valor tendrá el mismo valor que el mismo bit en la representación del objeto del tipo sin signo correspondiente (si hay M bits de valor en el tipo con signo y N en el tipo sin signo, entonces M ≤ N). Si el bit de signo es cero, no afectará el valor resultante. Si el bit de signo es uno, el valor se modificará de una de las siguientes maneras:

- el valor correspondiente con el bit de signo 0 es negado (signo y magnitud);

- el bit de signo tiene el valor - (2 M ) (complemento de dos);

- el bit de signo tiene el valor - (2 M - 1 ) (complemento de unos).

Cuál de estos aplica es definido por implementación, como si el valor con el bit de signo 1 y todos los bits de valor cero (para los dos primeros) o con el bit de signo y todos los bits de valor 1 (para el complemento de uno) es una representación trampa o un valor normal En el caso de signo y magnitud y el complemento de uno, si esta representación es un valor normal, se llama cero negativo.

Resumen

Creo que la intención es la misma para ambos estándares.

  • char , signed char y unsigned char tienen todos los bits participando en el valor

  • otros tipos enteros pueden tener bits de relleno que no participan en el valor. Un patrón de bits incorrecto en ellos puede implicar un valor no válido.

  • la interpretación es una representación binaria pura, algo cuya definición se expande en la cita C11 anterior.

Dos cosas que pueden no estar claras:

  • can -0 (para signo y magnitud y complemento de _ones) sea un valor de captura en C ++

  • ¿puede uno de los bits de relleno ser un bit de paridad (es decir, podemos modificar la representación si nos aseguramos de que los bits de relleno no se modifiquen o no)?

Sería conservador y asumiría que sí por los dos.

No se trata de una práctica recomendada (ni de un comportamiento indefinido ), sino de lo que realmente garantiza la norma c ++ en la cuestión de convertir todos los bytes de un tipo entero en el valor de (unsigned char)0 .

Las preguntas)

En el siguiente fragmento, ¿está garantizada la expresión utilizada por if-statement para ser verdadera en c ++ 11 ?

std::memset ( reinterpret_cast<char*> (&a), // int a; (unsigned char)0, sizeof (int) ); if (a == 0) { ... }

Al leer las citas del estándar C99 y C ++ 11 (más abajo en esta publicación) encontramos que C99 explícitamente garantiza que un tipo entero con todos los bits configurados a 0 representará el valor 0 en ese tipo.

No puedo encontrar esta garantía en el estándar C ++ 11.

  • ¿No hay tal garantía?
  • ¿El resultado del fragmento anterior es realmente específico de la implementación?

En C99 (ISO / IEC 9899: 1999)

5.2.1.2/1 caracteres multibyte

Un byte con todos los bits cero se interpretará como un carácter nulo independiente del estado de cambio. Tal byte no se producirá como parte de ningún otro carácter multibyte.

6.2.6.2/1 Tipos enteros

Los valores de los bits de relleno no están especificados. 45) Una representación de objeto válida (sin trampa) de un tipo de entero con signo donde el bit de signo es cero es una representación de objeto válida del tipo sin signo correspondiente, y representará el mismo valor.

Para cualquier tipo de entero, la representación del objeto donde todos los bits son cero debe ser una representación del valor cero en ese tipo.

En C ++ 11 (ISO / IEC 14882: 2011)

2.3 / 3 conjuntos de caracteres [lex.charset]

El conjunto de caracteres de ejecución básica y el conjunto de caracteres amplios de ejecución básica contendrán todos los miembros del conjunto de caracteres fuente básico, más los caracteres de control que representan alerta, retroceso y retorno de carro, más un carácter nulo (respectivamente, carácter ancho nulo), cuya representación tiene todos los bits cero .


No. No creo que esté realmente garantizado, pero es bastante vago.

Me sorprendería mucho que alguna vez haya habido una implementación de C ++ en la que todos los bits cero no sean una representación de 0 , pero creo que tal implementación podría ser conforme (aunque perversa).

Comencemos por considerar el estándar C99. (Sí, lo sé, la pregunta es sobre C ++; tengan paciencia conmigo). Dice que los bits de la representación del objeto de un tipo entero sin signo se dividen en dos grupos: bits de valor y relleno (no es necesario que haya ningún relleno) bits, y la mayoría de las implementaciones no los tienen). Los bits de valor constituyen una representación binaria pura; los bits de relleno no contribuyen al valor. Algunas combinaciones de bits de relleno podrían generar una representación de trampa .

Los tipos firmados son similares, con la adición de un bit de signo único. Los tipos con signo se pueden representar usando signo y magnitud , o complemento de dos , o el complemento de uno, pero de nuevo, los bits de relleno no contribuyen al valor, y algunas combinaciones de bits de relleno pueden generar representaciones de trampa.

Esta descripción no excluye la posibilidad de que, por ejemplo, un tipo entero más ancho que char pueda tener un solo bit de relleno que siempre debe ser 1; si es 0, tienes una representación de trampa. O, quizás más plausiblemente, podría tener un bit de paridad impar.

Después de que se publicó el estándar C99, el segundo Corrigendum técnico agregó la siguiente oración, que también aparece en C11.

Para cualquier tipo de entero, la representación del objeto donde todos los bits son cero debe ser una representación del valor cero en ese tipo.

Voy a enfatizar que esto fue agregado como texto normativo, no como una nota al pie, lo que sugiere (pero no prueba) que los miembros del comité consideraron que la garantía no estaba ya implícita en el estándar C99.

(C90 era mucho menos específico acerca de cómo se representan los tipos enteros. No mencionaba los bits de relleno, las representaciones de trampas o los complementos de dos y más. Yo diría que le dio a las implementaciones al menos tanta flexibilidad como C99).

Entonces, comenzando con C99 TC2, el lenguaje C garantiza que todos los bits cero es una representación de cero para cualquier tipo de entero. En C99 y C90, esa garantía no está indicada.

Eso es C. ¿Qué pasa con C ++?

El estándar C ++ 2011 parece proporcionar solo un poco más de especificidad sobre las representaciones de tipo entero como el antiguo estándar C de 1990. Requiere que los tipos firmados sean representados usando el complemento 2, el complemento 1 o la magnitud con signo. También requiere un "sistema de numeración binario puro". No menciona las "representaciones de trampas" ni los bits de relleno, excepto en el contexto de los campos de bits.

Por lo tanto, tanto en C90 como en C8 pre TC2, al menos teóricamente era posible que todos los bits cero fueran representaciones de trampas para un tipo entero. Los requisitos del estándar C ++ para tipos enteros son muy similares a los de C90 y C99. Requiere una "representación binaria pura", pero yo diría que eso se aplica, como lo hace en C99, solo a los bits de valor; aunque C ++ no menciona los bits de relleno, no los prohíbe.

Nuevamente, esto es principalmente de interés teórico (por lo tanto, la etiqueta de "abogado de idiomas"). El comité C se sintió libre de imponer el requisito de que todos los bits cero debieran ser una representación de cero porque todas las implementaciones ya lo satisfacían. Lo mismo es casi seguro que se aplica a C ++.


Nop. Por ejemplo, no hay nada en la Norma que prohíba una representación basada en prejuicios, solo exige que sea binaria.


Sí, está garantizado

Se garantiza que convertir todos los bytes / bits de un tipo entero hará que una instancia del tipo tenga el valor de cero ( 0 ), tal como lo indican los fragmentos a continuación del estándar mencionado.

3.9.1 / 7 Tipos fundamentales

Un sinónimo para tipo integral es tipo entero. Las representaciones de tipos integrales definirán valores mediante el uso de un sistema de numeración binario puro. 49

49 Representación posicional para enteros que usa los dígitos binarios 0 y 1, en los que los valores representados por bits sucesivos son aditivos, comienzan con 1 y se multiplican por la potencia integral sucesiva de 2, excepto tal vez para el bit con la posición más alta. (Adaptado del American National Dictionary for Information Processing Systems ).