c++ c if-statement language-lawyer

Declaraciones/definiciones como enunciados en C y C++



if-statement language-lawyer (4)

C ++ permitió que la "subestación" de una instrucción de iteración fuera implícitamente una declaración compuesta ([stmt.iter])

Si la subestación en un enunciado de iteración es una sola declaración y no una declaración compuesta, es como si se reescribiera para ser una declaración compuesta que contiene la declaración original. Ejemplo:

while (--x >= 0) int i;

puede ser reescrito de manera equivalente como

while (--x >= 0) { int i; }

el estándar C no tiene este lenguaje.

Además, la definición de una declaración cambió en C ++ para incluir una declaración de declaración , por lo que incluso si el cambio anterior no se realizó, aún sería legal.

La razón por la que agregar llaves hace que funcione es porque su declaración ahora se convierte en una declaración compuesta que puede incluir declaraciones.

Se le permite tener un identificador en un cuerpo de bucle sin llaves, por lo que puede hacer esto en su lugar:

int a = 5; for (int i = 0; i < 4; ++i) a;

Estaba confundido cuando esto no se compilaría en C:

int main() { for (int i = 0; i < 4; ++i) int a = 5; // A dependent statement may not be declaration return 0; }

Estoy acostumbrado a C ++ donde esto compilará. Me quedé mirando estupefacto durante un tiempo hasta que recordé una respuesta aquí en SO sobre cómo en C y C ++ diferentes cosas se consideran "declaraciones". Esto fue con respecto a una declaración de cambio. Una "declaración" después de los corchetes for debe estar presente tanto en C como en C ++. Esto puede hacerse tanto agregando un punto y coma como creando un bloque de corchete ondulado {}.

En C ++ "int a = 7;" se considera una declaración, definición e inicialización. En CI cree que también se considera todo esto, sin embargo, en C no se considera una "declaración".

¿Podría alguien aclarar exactamente por qué en C esto no es una declaración, mientras que en C ++ lo es? Esto confunde mi concepto de lo que es una afirmación, porque un idioma dice que sí, y otro dice que no, por lo que estoy un poco confundido.


De acuerdo con cppreference, C++ incluye los siguientes tipos de statements :

  1. declaraciones de expresión;
  2. declaraciones compuestas;
  3. declaraciones de selección;
  4. declaraciones de iteración;
  5. declaraciones de salto;
  6. declaraciones de declaración;
  7. probar bloques;
  8. bloques atómicos y sincronizados

Mientras que C considera seguir tipos de statements :

  1. declaraciones compuestas
  2. declaraciones de expresión
  3. declaraciones de selección
  4. declaraciones de iteración
  5. declaraciones de salto

Como puede observar, las declaraciones no se consideran statements en C, mientras que no es este caso en C ++.

Para C ++:

int main() { // start of a compound statement int n = 1; // declaration statement n = n + 1; // expression statement std::cout << "n = " << n << ''/n''; // expression statement return 0; // return statement } // end of compound statement

Para C:

int main(void) { // start of a compound statement int n = 1; // declaration (not a statement) n = n+1; // expression statement printf("n = %d/n", n); // expression statement return 0; // return statement } // end of compound statement, end of function body


En C ++ las declaraciones son enunciados mientras que en C las declaraciones no son enunciados. Entonces, según la gramática C en este ciclo for

for (int i = 0; i < 4; ++i) int a = 5;

int a = 5; debe ser una subestación del ciclo. Sin embargo, es una declaración.

Puede hacer que el código se compile en C utilizando la sentencia compuesta como, por ejemplo,

for (int i = 0; i < 4; ++i) { int a = 5; }

aunque el compilador puede emitir un mensaje de diagnóstico diciendo que la variable a no se usa.

Una consecuencia más que en las declaraciones C no son declaraciones. No puede colocar una etiqueta antes de una declaración en C. Por ejemplo, este programa

#include <stdio.h> int main(void) { int n = 2; L1: int x = n; printf( "x == %d/n", x ); if ( --n ) goto L1; return 0; }

no compila en C aunque compila como un programa C ++. Sin embargo, si para colocar una declaración nula después de la etiqueta, el programa compila.

#include <stdio.h> int main(void) { int n = 2; L1:; int x = n; printf( "x == %d/n", x ); if ( --n ) goto L1; return 0; }


En C ++, una declaración es (borrador estándar de C ++ 17)

excerpt from [gram.stmt] statement: labeled-statement attribute-specifier-seqopt expression-statement attribute-specifier-seqopt compound-statement attribute-specifier-seqopt selection-statement attribute-specifier-seqopt iteration-statement attribute-specifier-seqopt jump-statement declaration-statement attribute-specifier-seqopt try-block init-statement: expression-statement simple-declaration declaration-statement: block-declaration ...

Tenga en cuenta que hay declaraciones de declaración en C ++, que son declaraciones y son enunciados. Del mismo modo, las declaraciones simples son declaraciones init. Sin embargo, no todas las declaraciones son declaraciones. La gramática de las declaraciones contiene cosas que no están en la lista de declaraciones:

excerpt from [gram.dcl] declaration: block-declaration nodeclspec-function-declaration function-definition template-declaration deduction-guide explicit-instantiation explicit-specialization linkage-specification namespace-definition empty-declaration attribute-declaration block-declaration: simple-declaration asm-definition namespace-alias-definition using-declaration using-directive static_assert-declaration alias-declaration opaque-enum-declaration simple-declaration: decl-specifier-seq init-declarator-listopt ; attribute-specifier-seq decl-specifier-seq init-declarator-list ; attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ; ...

La lista de gramáticas de declaración continúa en algunas páginas.

En C, una declaración es (borrador estándar C11)

excerpt from Statements and blocks statement: labeled-statement compound-statement expression-statement selection-statement iteration-statement jump-statement

Tenga en cuenta que no hay declaraciones que sean declaraciones en C.

Entonces, el significado del enunciado es claramente diferente en los idiomas. El enunciado en C ++ parece tener un significado más amplio que el enunciado en C.