web-dev-qa-db-fra.com

Les différences entre initialiser, définir, déclarer une variable

Après avoir lu question , je connais les différences entre déclaration et définition. Cela signifie-t-il que définition est égale à déclaration plus initialisation?

60
Tony

Déclaration

Déclaration, généralement, fait référence à l’introduction d’un nouveau nom dans le programme. Par exemple, vous pouvez déclarer une nouvelle fonction en décrivant sa "signature":

void xyz();

ou déclarer un type incomplet:

class klass;
struct ztruct;

et enfin, pour déclarer un objet:

int x;

Il est décrit, dans la norme C++, au § 3.1/1 comme suit:

Une déclaration (Clause 7) peut introduire un ou plusieurs noms dans une unité de traduction ou redéclarer des noms introduits par des déclarations précédentes.

Définition

Une définition est une définition d'un nom précédemment déclaré (ou il peut s'agir à la fois d'une définition et d'une déclaration). Par exemple:

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

Plus précisément, le standard C++ le définit, au § 3.1/1, comme suit:

Une déclaration est une définition, sauf si elle déclare une fonction sans spécifier le corps de la fonction (8.4), elle contient le spécificateur extern (7.1.1) ou une spécification de liaison25 (7.5) et ni un initialiseur ni un corps de fonction, elle déclare membre de données statique dans une définition de classe (9.2, 9.4), c’est une déclaration de nom de classe (9.1), c’est une déclaration opaque-enum (7.2), c’est un modèle-paramètre (14.1), c’est un paramètre- déclaration (8.3.5) dans un déclarateur de fonction qui n'est pas le déclarant d'une définition de fonction ou une déclaration typedef (7.1.3), une déclaration d'alias (7.1.3), une déclaration d'utilisation (7.3. 3), une déclaration static_assert (clause 7), une déclaration d'attribut (clause 7), une déclaration vide (clause 7) ou une directive d'utilisation (7.3.4).

Initialisation

L'initialisation fait référence à "l'affectation" d'une valeur, au moment de la construction. Pour un objet générique de type T, il se présente souvent sous la forme:

T x = i;

mais en C++, cela peut être:

T x(i);

ou même:

T x {i};

avec C++ 11.

Conclusion

Cela signifie-t-il que définition est égale à déclaration plus initialisation?

Ça dépend. De quoi vous parlez. Si vous parlez d'un objet, par exemple:

int x;

Ceci est une définition sans initialisation. Au lieu de cela, voici une définition avec initialisation:

int x = 0;

Dans certains contextes, parler d’initialisation, de définition et de déclaration n’a aucun sens. Si vous parlez d'une fonction, par exemple, l'initialisation ne signifie pas grand chose.

La réponse est donc non: définition ne signifie pas automatiquement déclaration plus initialisation.

76
Shoe

La déclaration dit "cette chose existe quelque part":

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

La définition dit "cette chose existe ici; faites-en de la mémoire":

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

L'initialisation est optionnelle au point de définition pour les objets, et indique "voici la valeur initiale pour cette chose":

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

Parfois, c'est possible au moment de la déclaration:

struct T
{
   static int baz = 42;
};

… Mais cela entre dans des fonctionnalités plus complexes.

30

Pour C, au moins, selon C11 6.7.5:

Une déclaration spécifie l'interprétation et les attributs d'un ensemble d'identifiants. Une définition d'un identifiant est une déclaration pour cet identifiant qui:

  • pour un objet, le stockage est réservé à cet objet;

  • pour une fonction, inclut le corps de la fonction;

  • pour une constante d'énumération, est la (seule) déclaration de l'identifiant;

  • pour un nom typedef, est la première (ou la seule) déclaration de l'identifiant.

Par C11 6.7.9.8-10:

Un initialiseur spécifie la valeur initiale stockée dans un objet ... si un objet à stockage automatique n'est pas initialisé explicitement, sa valeur est indéterminée.

De manière générale, une déclaration introduit un identifiant et fournit des informations à ce sujet. Pour une variable, une définition est une déclaration qui alloue de la mémoire pour cette variable.

L'initialisation est la spécification de la valeur initiale à stocker dans un objet, ce qui n'est pas nécessairement identique à la première fois que vous lui attribuez explicitement une valeur . Une variable a une valeur lorsque vous la définissez, que vous lui donniez explicitement une valeur ou non. Si vous ne lui donnez pas explicitement de valeur et que la variable dispose d'un stockage automatique, elle aura une valeur initiale, mais cette valeur sera indéterminée. S'il dispose d'une mémoire statique, il sera implicitement initialisé en fonction du type (par exemple, les types de pointeur sont initialisés en pointeurs nuls, les types arithmétiques sont initialisés à zéro, etc.).

Donc, si vous définissez une variable automatique sans spécifier de valeur initiale, telle que:

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

Vous le définissez (et donc vous le déclarez également, car les définitions sont des déclarations), mais vous ne l'initialisez pas. Par conséquent, définition n'est pas égale à déclaration plus initialisation.

4
Paul Griffiths

"Cela signifie donc que définition est égale à déclaration plus initialisation."

Pas nécessairement, votre déclaration pourrait être sans aucune variable en cours d'initialisation, comme ceci:

 void helloWorld(); //declaration or Prototype.

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