Las diferencias entre inicializar, definir, declarar una variable

78

Después de leer la pregunta , sé las diferencias entre declaración y definición. Entonces, ¿significa que la definición es igual a la declaración más la inicialización?

Tony
fuente
1
La inicialización es para variables. La definición puede aplicarse también a funciones, en las que se define el cuerpo.
FKaria
Entonces, ¿te refieres a una variable?
Tony

Respuestas:

99

Declaración

Declaración, generalmente, se refiere a la introducción de un nuevo nombre en el programa. Por ejemplo, puede declarar una nueva función describiendo su "firma":

void xyz();

o declarar un tipo incompleto:

class klass;
struct ztruct;

y por último, pero no menos importante, para declarar un objeto:

int x;

Se describe, en el estándar C ++, en §3.1 / 1 como:

Una declaración (cláusula 7) puede introducir uno o más nombres en una unidad de traducción o volver a declarar nombres introducidos por declaraciones anteriores.

Definición

Una definición es una definición de un nombre previamente declarado (o puede ser tanto una definición como una declaración). Por ejemplo:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

Específicamente, el estándar C ++ lo define, en §3.1 / 1, como:

Una declaración es una definición a menos que declare una función sin especificar el cuerpo de la función (8.4), contiene el especificador extern (7.1.1) o una especificación de enlace25 (7.5) y no un inicializador ni un cuerpo de función, declara un miembro de datos estáticos en una definición de clase (9.2, 9.4), es una declaración de nombre de clase (9.1), es una declaración de enumeración opaca (7.2), es un parámetro de plantilla (14.1), es un parámetro- declaración (8.3.5) en un declarador de función que no es el declarador de una definición de función, o es una declaración typedef (7.1.3), una declaración de alias (7.1.3), una declaración using (7.3. 3), una declaración static_assert (cláusula 7), una declaración de atributo (cláusula 7), una declaración vacía (cláusula 7) o una directiva using (7.3.4).

Inicialización

La inicialización se refiere a la "asignación" de un valor, en el momento de la construcción. Para un objeto genérico de tipo T, a menudo tiene el formato:

T x = i;

pero en C ++ puede ser:

T x(i);

o incluso:

T x {i};

con C ++ 11.

Conclusión

Entonces, ¿significa que la definición es igual a la declaración más la inicialización?

Depende. De lo que estás hablando. Si está hablando de un objeto, por ejemplo:

int x;

Esta es una definición sin inicialización. Lo siguiente, en cambio, es una definición con inicialización:

int x = 0;

En cierto contexto, no tiene sentido hablar de "inicialización", "definición" y "declaración". Si habla de una función, por ejemplo, la inicialización no significa mucho.

Entonces, la respuesta es no : la definición no significa automáticamente declaración más inicialización.

Zapato
fuente
14
No del todo: int x;es tanto una definición como una declaración.
Angew ya no está orgulloso de SO
2
@Angew, gracias, agregué una definición más completa .
Zapato
Creo que la pregunta que OP mencionó en su publicación responde bastante bien a la definición y declaración. Pero la pregunta original era So does it mean definition equals declaration plus initialization.
Tahlil
@Tahlil, agregó una conclusión. Gracias por hacerme notar.
Zapato
3
@Tony Creo (por favor, que alguien me corrija si me equivoco para que aprendo) 'extern int x' lo hace solo una declaración, lo que significa que la definición se encuentra en otra parte. Mientras que 'int x' en realidad lo define, aunque se le asigna un valor de basura aleatorio, a menos que lo inicialice específicamente como 'int x = 5'.
mocoso
41

La declaración dice "esta cosa existe en alguna parte":

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

La definición dice "esta cosa existe aquí; haz memoria para ella":

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

La inicialización es opcional en el punto de definición de los objetos y dice "aquí está el valor inicial para esto":

int bar = 0;     // variable
int T::baz = 42; // static member variable

A veces es posible en el momento de la declaración:

struct T
{
   static int baz = 42;
};

… Pero eso es entrar en funciones más complejas.

Carreras de ligereza en órbita
fuente
Muy bien explicado, excepto que la inicialización es un poco más compleja que eso. (Esto no sería C ++ si fuera tan simple). La inicialización incluye cosas como la inicialización cero de variables con vida estática y constructores predeterminados, así como lo que muestra. (Y para aumentar la confusión: en C, la inicialización puede ser la primera vez que se asigna la variable; por ejemplo, en declaraciones como "tomar el valor de una variable no inicializada". No me sorprendería si algo de esto también se deslizara C ++.)
James Kanze
Ah, y también hay casos especiales en los que C ++ permite la especificación de la inicialización en una declaración.
James Kanze
1
@JamesKanze: Decidió mantenerlo súper simple para estos propósitos
Lightness Races in Orbit
6

Para C, al menos, según C11 6.7.5:

Una declaración especifica la interpretación y los atributos de un conjunto de identificadores. Una definición de un identificador es una declaración para ese identificador que:

  • para un objeto, hace que el almacenamiento se reserve para ese objeto;

  • para una función, incluye el cuerpo de la función;

  • para una constante de enumeración, es la (única) declaración del identificador;

  • para un nombre typedef, es la primera (o única) declaración del identificador.

Según C11 6.7.9.8-10:

Un inicializador especifica el valor inicial almacenado en un objeto ... si un objeto que tiene almacenamiento automático no se inicializa explícitamente, su valor es indeterminado.

Entonces, en términos generales, una declaración introduce un identificador y proporciona información sobre él. Para una variable, una definición es una declaración que asigna almacenamiento para esa variable.

La inicialización es la especificación del valor inicial que se almacenará en un objeto, que no es necesariamente el mismo que la primera vez que le asigna explícitamente un valor. Una variable tiene un valor cuando la define, ya sea que le dé explícitamente o no un valor. Si no le da un valor explícitamente y la variable tiene almacenamiento automático, tendrá un valor inicial, pero ese valor será indeterminado. Si tiene almacenamiento estático, se inicializará implícitamente según el tipo (por ejemplo, los tipos de puntero se inicializan a punteros nulos, los tipos aritméticos se inicializan a cero, etc.).

Entonces, si define una variable automática sin especificar un valor inicial para ella, como:

int myfunc(void) {
    int myvar;
    ...

Lo está definiendo (y por lo tanto también lo está declarando, ya que las definiciones son declaraciones), pero no lo está inicializando. Por lo tanto, la definición no es igual a la declaración más la inicialización.

Crowman
fuente
En C ++, la inicialización es significativamente diferente. (C también tiene el equivalente a la inicialización cero de objetos con vida estática.)
James Kanze
@JamesKanze: Sí, desafortunadamente esta pregunta está etiquetada con C y C ++, lo cual no es muy útil en los puntos en los que difieren.
Crowman
Bastante. Para los tipos compatibles, la intención (al menos originalmente) en C ++ era que se comportaran igual que en C; de hecho, creo que todavía se comportan igual en todos los casos en los que los lenguajes son compatibles. Pero la redacción utilizada para definir este comportamiento es bastante diferente.
James Kanze
1

"Entonces, ¿significa que la definición es igual a la declaración más la inicialización?"

No necesariamente, su declaración podría ser sin ninguna variable inicializada como:

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
Shoaib
fuente