c standards language-lawyer

¿Cuáles son las restricciones en el estándar C?



standards language-lawyer (6)

Los estándares C hablan de restricciones , por ejemplo, ISO / IEC 9899: 201x define el término

restricción
Restricción, ya sea sintáctica o semántica, mediante la cual se debe interpretar la exposición de elementos del lenguaje.

y dice en el capítulo Conformidad.

Si un requisito '''' debe '''' o ''no debe'' ''que aparece fuera de una restricción o se viola una restricción de tiempo de ejecución, el comportamiento no está definido.

En el capítulo Entorno , Subsección Diagnóstico se dice.

Una implementación conforme producirá al menos un mensaje de diagnóstico (identificado de 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 se especifica explícitamente como no definido o implementación definido

Por lo tanto, es importante saber cuáles son las restricciones en C, por ejemplo, para que los escritores de compiladores juzguen cuándo se requieren los diagnósticos, o para los programadores de C cuando se pueden esperar diagnósticos en lugar de solo un comportamiento indefinido.
Ahora, hay secciones en todo el documento estándar con el título Restricciones , pero no puedo encontrar una redacción definitiva en cuanto a qué es exactamente el término restricción en la norma.

  • ¿Son las restricciones todo lo que aparece en las secciones tituladas Restricciones ?
  • ¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?
  • ¿Hay una descripción completa de la restricción en el estándar que no cumplí?

¿Son las restricciones todo lo que aparece en las secciones tituladas Restricciones ?

Sí. Todas las restricciones sintácticas y semánticas mencionadas en el estándar son restricciones.

Por ejemplo, una restricción en las expresiones constantes (C11-6.6 / 3):

Las expresiones constantes no contendrán operadores de asignación, incremento, decremento, función-llamada o coma, excepto cuando estén contenidas dentro de una subexpresión que no se evalúa. 115)

Por lo tanto, las expresiones constantes

3 = 5; 10++;

muestra violación de restricción.

Tenga en cuenta que, en este caso, tanto el requisito como la restricción son violados.

¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?

Para la conformidad estándar C, sí. A se requerirá en la expresión constante entera (C11-6.6 / 6):

Una expresión constante de entero 117) tendrá tipo entero [...]

Por ejemplo, se requiere una expresión constante de enteros para el tamaño de una matriz de longitud no variable. Por lo tanto,

int arr[5+1.5];

Viola el requisito de deber. El tipo de expresión 5+1.5 no es un tipo entero. Este requisito está fuera de restricción.

Se debe tener en cuenta que un requisito de la obligación también puede ser una restricción.


¿Son las restricciones todo lo que aparece en las secciones tituladas Restricciones?

En el sentido de n1570 3.8 (una restricción impuesta a los programas que requiere una implementación conforme para emitir un mensaje de diagnóstico en tiempo de compilación cuando se viola), creo que sí.

¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?

En el sentido de 3.8, creo que sí, pero por una razón más circular: la estructura de la norma es bastante formal. Siempre que sea aplicable, parece haber una sección de Restricciones explícita. Por lo tanto, entiendo que, por definición, cualquier cosa que no esté en una sección de Restricciones no es una restricción en el sentido de 3.8.
Hay unas pocas cláusulas "deben" fuera de las secciones de Restricciones que aparecen ejecutables por completo en tiempo de compilación, cf. abajo para algunos ejemplos. A menudo están en secciones semánticas adyacentes. Es posible que me falten las sutilezas que impiden la detección en tiempo de compilación en el caso general (para que un diagnóstico no pueda ser obligatorio), o quizás el estándar no sea completamente consistente. Pero creo que un compilador podría simplemente traducir un programa violatorio, exactamente porque los requisitos no están en una sección de Restricciones .

¿Hay una descripción completa de la restricción en el estándar que no cumplí?

Creo que 3.8 es todo lo que obtienes. Intento explorar el término a continuación y acepto que la definición es insatisfactoria.

Miré más profundamente en el estándar para descubrir eso. Aquí está mi investigación.

El término restricción

Empecemos con lo básico. La definición de "restricción" en 3.8 que usted cita es sorprendentemente difícil de entender, al menos sin contexto ("restricción, ya sea sintáctica o semántica, mediante la cual se debe interpretar la exposición de elementos del lenguaje"). "Restricción" y "restricción" son sinónimos, por lo que la nueva redacción no agrega mucho; ¿Y qué se entiende por "exposición de elementos del lenguaje"? Exposición es una palabra con varios significados; Tomemos "escritura o discurso destinado principalmente a transmitir información" de Dictionary.com , y asumamos que se refieren al estándar con eso. Entonces significa básicamente que una restricción en esta norma es una restricción de lo que se dice en esta norma. Wow, no lo habría adivinado.

Restricciones según 3.8

Pragmáticamente, el solo examen de las secciones de Restricciones reales en el estándar muestra que enumeran las restricciones de tiempo de compilación impuestas a los programas que se ajustan. Esto tiene sentido porque solo las restricciones de tiempo de compilación se pueden verificar en tiempo de compilación. Estas restricciones adicionales son aquellas que no se pueden expresar en la sintaxis de C. 1

Restricciones fuera de las secciones de Restricciones

La mayoría de los usos de "deben" fuera de las secciones de Restricciones imponen restricciones en una implementación conforme. Ejemplo: "Todos los objetos con duración de almacenamiento estático deben inicializarse (configurarse en sus valores iniciales) antes del inicio del programa", un trabajo de una implementación conforme.

Sin embargo, hay algunas cláusulas "deben" que imponen restricciones a un programa (no a la implementación) fuera de las secciones de Restricciones . Yo diría que la mayoría cae en la misma categoría que las "restricciones de tiempo de ejecución [...] en un programa cuando se llama una función de biblioteca" mencionada en 3.18. Parecen ser restricciones de tiempo de ejecución que generalmente no son detectables en tiempo de compilación (por lo que los diagnósticos no pueden ser obligatorios).

Aquí están algunos ejemplos.

En 6.5 / 7 n1570 se detallan las reglas de alias muy debatidas:

Un objeto tendrá acceso a su valor almacenado solo por una expresión lvalue que tenga uno de los siguientes tipos:

  • Un tipo compatible con el tipo efectivo del objeto.
  • una versión calificada de un tipo compatible con el tipo efectivo del objeto, [...]

En 6.5.16.1, "Asignación Simple":

Si el valor que se almacena en un objeto se lee desde otro objeto que se superpone de alguna manera al almacenamiento del primer objeto, entonces la superposición será exacta [..] ".

Otros ejemplos se refieren a la aritmética de punteros (6.5.6 / 8).

Deberán incluirse cláusulas que puedan estar en las secciones de Restricciones.

Pero luego hay otras cláusulas cuya violación debería ser detectable en el momento de la compilación; No habría parpadeado si hubieran aparecido en la sección de Restricciones respectiva.

  • 6.6 / 6, "Los operadores de conversión en una expresión constante de entero solo convertirán los tipos aritméticos en tipos enteros" (bajo "Semántica"); ¿Qué puede detectar en tiempo de compilación si no puede detectar tipos de constantes y moldes?
  • 6.7 / 7, "Si se declara un identificador para un objeto sin vinculación, el tipo para el objeto se completará al final de su declarador" (bajo "Semántica"). Para mí, parece ser una tarea básica del compilador para detectar si un tipo está completo en algún punto del código. Pero por supuesto, nunca he escrito un compilador de C.

Hay algunos ejemplos más. Pero como dije, creo que no se requiere una implementación para diagnosticar violaciones. Un programa infractor que logra escabullirse del compilador simplemente expone un comportamiento indefinido.

1 Por ejemplo, entiendo que la sintaxis no se ocupa de los tipos, solo tiene "expresiones" genéricas. Por lo tanto, cada operador tiene una sección de Restricciones que detalla los tipos permisibles de sus argumentos. Ejemplo para operadores de cambio: "Cada uno de los operandos tendrá un tipo entero". Un programa que está intentando cambiar los bits de un flotador está violando esta restricción, y la implementación debe emitir un diagnóstico.

¿Son las restricciones todo lo que aparece en las secciones tituladas Restricciones?

Parece que son en su mayoría (hay algunos casos que no lo son, fx: se afirma que "Incrementar es equivalente a agregar 1" en una de las secciones de restricción).

¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?

No he visto una "restricción" fuera de esas secciones.

¿Hay una descripción completa de la restricción en el estándar que no cumplí?

Probablemente no, si hubiera un autoritario tal, estaría en la norma y probablemente serían las secciones de "restricción" (y se mencionó explícitamente que todas estas son "restricciones").

Mi interpretación es que el capítulo 3 debe interpretarse de modo que cada uso de los términos definidos tenga el significado definido en esa sección. Especialmente en todos los lugares donde se usa el término "restricción", debe entenderse de acuerdo con su primera cita.

Su segunda cita no es una excepción. En la definición del término "restricción" se señala que no hay ningún requisito de que la restricción se denomine explícitamente una restricción. Esto significa que debe determinar si es una "restricción" comprobando si se trata de una restricción de este tipo.

Sin embargo, parece que hay bastantes ejemplos de "debe" y "no debe" que podrían tomarse como tales restricciones sin que se las exprese explícitamente como tales. Eso dejaría todas las ocurrencias "deberá" y "no deberá" exigir o prohibir un determinado comportamiento de la implementación, y si no se cumplen, entonces sí el comportamiento puede ser indefinido (ya que está utilizando una implementación que no lo hace) t se ajustan a la norma).

Parece que todo lo que se ajusta a la definición de "restricción" aparece bajo una sección de "restricción", y todo en las secciones de "restricción" parece ser "restricciones".


restricción

Restricción, ya sea sintáctica o semántica, mediante la cual se debe interpretar la exposición de elementos del lenguaje.

Esto significa que cada restricción explícita para la lógica del programa o la sintaxis establecida por el estándar c de cualquier manera es una restricción. Esto incluye restricciones sintácticas (por ejemplo, los bloques deben terminarse con un ; ) y restricciones semánticas (por ejemplo, no debe usar una variable antes de inicializarla), básicamente todo lo que es sintácticamente (notación) o semánticamente (uso de la notación correcta ) no permitido o definido como no permitido (comportamiento indefinido).

¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?

Creo que todos los requisitos explícitos para la programación en el lenguaje C caen bajo una restricción sintáctica o semántica.

¿Hay una descripción completa de la restricción en el estándar que no cumplí?

No que yo sepa.


El comité C abordó este tema en la respuesta al Informe de defectos # 033 . La pregunta en ese informe de defecto fue:

¿Se requiere una implementación conforme para diagnosticar todas las infracciones de las declaraciones "deberá" y "no deberá" en el estándar, incluso si esas declaraciones se producen fuera de una sección etiquetada como Restricciones?

El autor de ese informe de defectos sugirió un par de posibles formas alternativas de interpretar el lenguaje de la norma. La segunda alternativa que enumeró dijo (en parte):

Las reglas de sintaxis son aquellos elementos listados en las secciones de Sintaxis del estándar. Las restricciones son aquellos elementos enumerados en las secciones Restricciones de la norma.

Parte de la respuesta del comité fue:

La interpretación sugerida # 2 es la correcta.

Creo que cubre sus preguntas bastante completamente, pero solo para expresar las respuestas a sus preguntas más directamente:

  • ¿Son las restricciones todo lo que aparece en las secciones tituladas Restricciones?
  • ¿Todos los requisitos que se establecen fuera de esas secciones no son una restricción?

Una "restricción" es un requisito que se establece en una sección marcada explícitamente como "Restricciones". Cualquier requisito establecido fuera de dicha sección no es una restricción.

  • ¿Hay una descripción completa de la restricción en el estándar que no cumplí?

Por lo menos que yo sepa, el estándar en no contiene una declaración más específica sobre lo que es o no una restricción, pero el informe de defectos vinculado sí lo hace.


En mi trabajo en ingeniería de requisitos, las palabras "restricción" y "requisito" tienen un alcance diferente. Es importante, también para el estándar, definirlos explícitamente. Busqué la palabra "restricción" en el estándar y parece que puedo sacar la siguiente conclusión:

Una restricción es una limitación de la entrada (condición previa) o la salida (condición posterior) del comportamiento que describe la sección de la norma. Para entrada, significa que la entrada debe cumplir con la restricción (por ejemplo, argc será positivo). Para salida, significa que debe satisfacer la restricción para que cualquier unidad siguiente del estándar tenga una entrada bien definida (su condición previa).

Un requisito es parte de la especificación del comportamiento de la sección de la norma. "Shall" es una descripción positiva de lo que se requiere; "no debe" es generalmente una limitación, pero no una restricción, aunque puede participar en el cumplimiento de una restricción en su salida.

Las restricciones y los requisitos se pueden ver como "interfaces externas" (las restricciones) y "comportamiento / procesamiento del sistema" (los requisitos).

Por lo general, denota un requisito (una frase sin "debe" no es un requisito). "Shall" utilizado en una restricción se usa para definir la entrada o la salida (por ejemplo, argc será positivo) o especifica el comportamiento relacionado con la validación de la restricción (por ejemplo, "... dará un mensaje de diagnóstico").

En sentido estricto, "debe" utilizado en la especificación del comportamiento de validación de una restricción de entrada no debe aparecer en la sección de restricciones (no debe aparecer en la especificación de la interfaz) sino en una sección de procesamiento (sección de comportamiento).

Tenga en cuenta que no puede haber validación de una restricción de salida ya que la salida debe cumplir con la especificación; solo un uit siguiente puede verificar esas restricciones si están en sus restricciones de entrada.

Esta puede ser una visión personal pero parece ajustarse a los usos de estas palabras en el estándar.