1039 votes

Quelle est la différence entre une définition et une déclaration ?

Comme le titre l’indique, la signification des deux m’échappe.

1043voto

sbi Points 100828

Une déclaration introduit un identifiant et décrit son type, du type, de l'objet ou de la fonction. Une déclaration est ce que le compilateur a besoin pour accepter les références à cet identifiant. Ces déclarations:

extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for class declarations

Une définition réellement instancie/implémente cet identifiant. C'est ce que l'éditeur de liens besoins afin de lier les références à ces entités. Ce sont des définitions correspondant aux déclarations ci-dessus:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

Une définition peut être utilisé à la place d'une déclaration.

Un identificateur peut être déclaré comme souvent que vous le souhaitez. Ainsi, la suite est légal en C et C++:

double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);

Cependant, il doit être défini exactement une fois. Si vous oubliez de définir quelque chose qui a été déclaré et référencé quelque part, puis l'éditeur de liens ne sais pas quoi lier les références à et se plaint d'un manque de symboles. Si vous définissez quelque chose plus d'une fois, l'éditeur de liens ne sais pas laquelle des définitions de références de lien et se plaint dupliqué symboles.


Depuis le débat de ce qu'est une classe de déclaration par rapport à un classe de définition en C++ revient sans cesse (dans les réponses et commentaires à d'autres questions) , je vais coller une citation de la norme C++ ici.
À 3.1/2, C++03, dit:

Une déclaration est une définition à moins qu'il [...] est un nom de classe de la déclaration [...].

3.1/3 donne quelques exemples. Parmi eux:

struct S { int a; int b; }; // définit S, S::a et S::b
struct S; // déclare S

Pour résumer: La norme C++ considère struct x; à être d'une déclaration et d' struct x {}; d'une définition. (En d'autres termes, la "déclaration anticipée" est un terme impropre, car il n'y a pas d'autres formes de déclarations de classe en C++.)

Grâce à litb (Johannes Schaub) qui a creusé le chapitre et le verset dans l'une de ses réponses.

189voto

Michael Kristofik Points 16035

À partir de la norme C++ section 3.1:

Une déclaration introduit les noms dans une unité de traduction ou redeclares noms introduits par le précédent les déclarations. Une déclaration précise l'interprétation et les attributs de ces noms.

Le paragraphe suivant unis (l'emphase est mienne) qu'une déclaration est une définition , à moins que...

... il déclare une fonction sans en préciser la fonction du corps

void sqrt(double);  // declares sqrt

... il déclare un membre statique dans une définition de classe

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

... il déclare un nom de classe

class Y;

... il contient de l' extern mot, sans un initialiseur ou corps de la fonction

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

... ou est un typedef ou using déclaration.

typedef long LONG_32;  // declares LONG_32
using namespace std;   // declares std

Maintenant, pour la grande raison pour laquelle il est important de comprendre la différence entre une déclaration et définition: Une Définition de la Règle. À partir de la section 3.2.1 de la norme C++:

Aucune unité de traduction doit contenir plus d'une définition de variable, fonction, type de classe, de type énumération, ou d'un modèle.

165voto

plinth Points 26817

Déclaration « Quelque part, il existe un truc ».

Définition : «.. .et ici que c’est ! »

54voto

Il y a des cas limites en C++ (certains d'entre eux dans C aussi). Envisager

T t;

Que peut être une définition ou d'une déclaration, en fonction du type T est:

typedef void T();
T t; // declaration of function "t"

struct X { 
  T t; // declaration of function "t".
};

typedef int T;
T t; // definition of object "t".

En C++, lors de l'utilisation de modèles, il y a un autre cas limite.

template <typename T>
struct X { 
  static int member; // declaration
};

template<typename T>
int X<T>::member; // definition

template<>
int X<bool>::member; // declaration!

La dernière déclaration était pas une définition. C'est la déclaration explicite de la spécialisation du membre statique d' X<bool>. Il indique au compilateur: "Si il s'agit de l'instanciation X<bool>::member, puis de ne pas instancier la définition de la membre depuis le premier modèle, mais l'utilisation de la définition que l'on trouve ailleurs". Pour en faire une définition, vous devez fournir un initialiseur

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.

37voto

AVD Points 57984

Déclaration

Les déclarations de dire au compilateur qu'une élément de programme ou le nom existe. Un déclaration introduit une ou plusieurs les noms dans un programme. Les déclarations peuvent plus d'une fois dans un programme. Ainsi, les classes, structures, les types énumérés, et d'autres types définis par l'utilisateur peuvent être déclarés pour chaque unité de compilation.

Définition

Définitions de spécifier quel est le code ou les données le nom décrit. Un nom doit être déclarée avant d'être utilisée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X