Comme le titre l’indique, la signification des deux m’échappe.
Réponses
Trop de publicités?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.
À 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.
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.
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.