Basado en esto (C11 6.4.4 / 2):

Restricciones

2 Cada constante tendrá un tipo y el valor de una constante estará en el rango de valores representables para su tipo.

Está escribiendo esto correcta:

unsigned long long int a=18446744073709551615;

Como el tipo de constante entera (que es una constante decimal ) no puede ser unsigned. Por lo tanto, el valor no está en el rango representable.

¿Qué pasa exactamente? el valor no está en el rango representable de la constante decimal. ?

Si tengo razón, la constante entera puede extenderse si no hay ningún tipo en la lista correspondiente que pueda representar la constante. El problema aquí es que las constantes decimales se pueden extender solo a constantes enteras con signo. Entonces el número 18446744073709551615 no tiene tipo.

¿Cómo podría ser la conversión de sin tipo a unsigned long long int?

4
Sabrina 7 mar. 2017 a las 02:05

2 respuestas

La mejor respuesta

Basado en dos largos hilos de comentarios que finalmente llegaron a algún tipo de conclusión, arriesgaré esta respuesta a la pregunta:

Está escribiendo esto correctamente:
unsigned long long int a=18446744073709551615;

Respuesta: Quizás; depende de la implementación.

En una implementación conforme, un long long int debe ser capaz de representar números hasta el mínimo LLONG_MAX, que es +9223372036854775807 (2 63 −1) (§5.2.4.2. 1) Dado que el número en cuestión es algo mayor que eso, no hay garantía de que encajará en un long long y, por lo tanto, no hay garantía de que sea representable. Si no es representable, el programa está violando una restricción (en §6.4.4.1), y la implementación debe responder a una violación de restricción al producir un mensaje de diagnóstico.

Sin embargo, una implementación dada es completamente gratuita para hacer long long int un tipo más amplio. Alternativamente, puede aprovechar §6.2.5 para 4 ("También puede haber tipos enteros con signo ampliado definidos por la implementación") para definir otro tipo, digamos int128_t, que es más ancho que long long int . Por lo tanto, el número puede ser representable en una implementación conforme, y el uso del programa con dicha implementación es completamente válido, como se indica en §4 párrafo 7, que establece que un programa conforme "es uno que es aceptable para una implementación conforme". Por lo tanto, un programador puede hacer uso de su conocimiento sobre lo que es aceptable para la implementación que está utilizando, y si la constante entera es aceptable para su implementación, entonces no es necesario un diagnóstico.

§4 también define una categoría más fuerte de programas, programas estrictamente conformes (párrafo 5), que debería ser portátil entre todas las implementaciones conformes. La constante entera anterior no es estrictamente conforme, por lo que la validez del programa depende de la implementación.

En una nota práctica, tanto clang como gcc aceptan el programa, pero no porque tengan enteros más amplios. El diagnóstico producido es:

advertencia: el entero literal es demasiado grande para ser representado en un tipo entero con signo, interpretando como sin signo [-Wimplicitly-unsigned-literal]

Que es suficiente para cumplir con el estándar y que especifica el comportamiento que están a punto de adoptar. Una vez que se produce el diagnóstico requerido, el estándar C ya no se aplica. El programador ha sido advertido, y si la implementación aún produce un ejecutable, depende de él documentar qué hace ese ejecutable. No hay diferencia entre violaciones de restricciones, como en esta pregunta, o errores de sintaxis: si un compilador conforme desea aceptar una sintaxis no definida en el estándar C (tal vez con la expectativa de que será parte de un estándar futuro), es libre de hacerlo siempre que produzca el diagnóstico requerido. Si un compilador detecta automáticamente Java, o C ++, o Python, y elige producir un ejecutable "apropiado", eso está fuera del estándar C porque el programa no es un programa C y el programador ha sido informado de ese hecho

Para enteros más grandes, el mensaje producido por clang y gcc es

error: el entero literal es demasiado grande para representarse en cualquier tipo entero

Y no se produce ningún ejecutable. Esto también cumple con el estándar, con algo menos de controversia.

3
rici 7 mar. 2017 a las 01:52

1

2

3 4 2

5

Si bien esto técnicamente no es un comportamiento indefinido, no se debe permitir que el compilador continúe compilando y produciendo un ejecutable. La mayoría de los compiladores, con razón, dejarán de compilar dicho código.


(Citado de: ISO / IEC 9899: 201x)

1 (3. Términos, definiciones y símbolos 3.8 restricción 1)
restricción, ya sea sintáctica o semántica, por la cual la exposición de elementos del lenguaje es ser interpretado

2 (6.4.4 Constantes 2)
Cada constante tendrá un tipo

3 (6.4.4.1 Constantes enteras 5)
El tipo de una constante entera es el primero de la lista correspondiente en la que su valor puede estar representado

4 (6.4.4.1 Constantes enteras 6)
Si una constante entera no puede ser representada por ningún tipo en su lista y no tiene un tipo entero extendido, entonces la constante entera no tiene tipo.

5 (5.1.1.3 Diagnóstico 1)
Una implementación conforme producirá al menos un mensaje de diagnóstico (identificado en una manera definida por la implementación) si una unidad de traducción de preprocesamiento o una unidad de traducción contiene una violación de cualquier regla o restricción de sintaxis, incluso si el comportamiento también es explícitamente especificado como indefinido o definido por la implementación.

2
2501 7 mar. 2017 a las 00:32