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
:
- declaraciones de expresión;
- declaraciones compuestas;
- declaraciones de selección;
- declaraciones de iteración;
- declaraciones de salto;
- declaraciones de declaración;
- probar bloques;
- bloques atómicos y sincronizados
Mientras que C considera seguir tipos de statements
:
- declaraciones compuestas
- declaraciones de expresión
- declaraciones de selección
- declaraciones de iteración
- 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.