Question

Le sens des deux m'échappe.

Était-ce utile?

La solution

Une déclaration introduit un identifiant et décrit son type, qu'il s'agisse d'un type, d'un objet ou d'une fonction. Une déclaration est ce dont le compilateur a besoin pour accepter les références à cet identifiant. Ce sont des 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 type declarations

Une définition instancie / implémente effectivement cet identifiant. C'est ce dont l'éditeur de liens a besoin pour lier des références à ces entités. Voici les 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ée à la place d'une déclaration.

Un identifiant peut être déclaré aussi souvent que vous le souhaitez. Ainsi, ce qui suit 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, l'éditeur de liens ne sait pas à quoi lier les références et se plaint d'un symbole manquant. Si vous définissez quelque chose plus d'une fois, l'éditeur de liens ne sait pas laquelle des définitions avec lesquelles lier les références et se plaindre des symboles dupliqués.

Depuis le débat sur ce qui constitue une déclaration de classe par rapport à une définition de classe en C ++, les réponses (et les commentaires à d'autres questions) ne cessent de se coller. citation de la norme C ++ ici.
En 3.1 / 2, C ++ 03 dit:

  

Une déclaration est une définition sauf si [...] est une déclaration de nom de classe [...].

3.1 / 3 donne ensuite quelques exemples. Parmi eux:

[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b [...]
struct S; // declares S
—end example

En résumé: la norme C ++ considère que struct x; est une déclaration et struct x {}; une définition . (En d’autres termes, & "; Transmettre la déclaration &"; Un abus de langage , car il n’existe aucune autre forme de déclaration de classe en C ++.)

Merci à litb (Johannes Schaub) qui a mis au jour le chapitre et le verset dans l'un de ses réponses.

Autres conseils

Dans la section 3.1 de la norme C ++ standard:

  

Une déclaration introduit les noms dans une unité de traduction ou redéclaire les noms introduits par les précédentes.   déclarations. Une déclaration spécifie l'interprétation et les attributs de ces noms.

Le paragraphe suivant indique (souligné par moi) qu'une déclaration est une définition , sauf si ...

... il déclare une fonction sans spécifier le corps de la fonction & # 8217;

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 le extern mot clé sans initialiseur ni corps de fonction:

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

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

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

Maintenant, voici la principale raison pour laquelle il est important de comprendre la différence entre une déclaration et une définition: la règle de définition unique . A partir de la section 3.2.1 de la norme C ++:

  

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

Déclaration: & "Quelque part, il existe un foo. &";

Définition: & «; et le voici!» & «;

.

Il existe des cas intéressants en C ++ (certains en C aussi). Considérer

T t;

Cela peut être une définition ou une déclaration, selon le 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 existe un autre cas.

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 n'était pas une définition. C'est la déclaration d'une spécialisation explicite du membre statique de X<bool>. Il indique au compilateur: & "S'il s'agit d'instancier X<bool>::member, n'instanciez pas la définition du membre à partir du modèle principal, mais utilisez la définition trouvée 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 indiquent au compilateur qu’un   L'élément de programme ou le nom existe. UNE   déclaration introduit un ou plusieurs   noms dans un programme. Les déclarations peuvent   se produire plus d'une fois dans un programme.   Par conséquent, les classes, les structures,   types énumérés et autres   types définis par l'utilisateur peuvent être déclarés pour   chaque unité de compilation.

Définition

  

Les définitions spécifient quel code ou quelle donnée   le nom décrit. Un nom doit être   déclarée avant de pouvoir être utilisée.

D'après la norme C99, 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é pour cet objet;
  • pour une fonction, inclut le corps de la fonction;
  • pour une constante d’énumération ou un nom de typedef, est la (seule) déclaration de la identifiant.

À partir de la norme C ++, 3.1 (2):

Une déclaration est une définition sauf si elle déclare une fonction sans spécifier le corps de la fonction, elle contient le spécificateur extern ou une spécification de liaison et ne contient ni initialiseur ni corps de la fonction, elle déclare une image statique. membre de données dans une déclaration de classe, il s’agit d’une déclaration de nom de classe ou d’une déclaration typedef, d’une déclaration using ou d’une directive using.

Ensuite, il y a quelques exemples.

Curieusement (ou pas, mais cela me surprend un peu), typedef int myint; est une définition en C99, mais seulement une déclaration en C ++.

De wiki.answers.com:

Le terme déclaration signifie (en C) que vous indiquez au compilateur le type, la taille et, dans le cas d'une déclaration de fonction, le type et la taille de ses paramètres de variable, ou le type ou la fonction défini par l'utilisateur de votre programme. Aucun espace n'est réservé en mémoire pour aucune variable en cas de déclaration. Cependant, le compilateur sait combien d’espace doit être réservé au cas où une variable de ce type serait créée.

Par exemple, voici toutes les déclarations:

extern int a; 
struct _tagExample { int a; int b; }; 
int myFunc (int a, int b);

D’un autre côté, la définition signifie qu’en plus de tout ce que fait la déclaration, l’espace est également réservé en mémoire. Vous pouvez dire & Quot; DEFINITION = DECLARATION + RESERVATION SPATIALE & Quot; Voici des exemples de définition:

int a; 
int b = 0; 
int myFunc (int a, int b) { return a + b; } 
struct _tagExample example; 

voir réponses .

Mise à jour C ++ 11

Puisque je ne vois pas de réponse pertinente pour C ++ 11, en voici une.

Une déclaration est une définition sauf si elle déclare un / n:

  • énumération opaque - enum X : int;
  • paramètre de modèle - T dans template<typename T> class MyArray;
  • déclaration de paramètre - x et y dans int add(int x, int y);
  • déclaration d'alias - using IntVector = std::vector<int>;
  • déclaration d'assertion statique - static_assert(sizeof(int) == 4, "Yikes!")
  • déclaration d'attribut (défini par l'implémentation)
  • déclaration vide ;

Clauses supplémentaires héritées de C ++ 03 par la liste ci-dessus:

  • déclaration de fonction - add dans extern int a;
  • spécificateur externe contenant une déclaration ou un spécificateur de liaison - extern "C" { ... }; ou class C { static int x; };
  • membre de données statique dans une classe - x dans struct Point;
  • déclaration de classe / struct - typedef int Int;
  • déclaration typedef - using std::cout;
  • using declaration - using namespace NS;
  • using directive - <=>

Un modèle-déclaration est une déclaration. Un modèle-déclaration est également une définition si sa déclaration définit une fonction, une classe ou un membre de données statique.

Exemples de normes qui différencient déclaration et définition et que j'ai trouvés utiles pour comprendre les nuances entre elles:

// except one all these are definitions
int a;                                  // defines a
extern const int c = 1;                 // defines c
int f(int x) { return x + a; }          // defines f and defines x
struct S { int a; int b; };             // defines S, S::a, and S::b
struct X {                              // defines X
    int x;                              // defines non-static data member x
    static int y;                       // DECLARES static data member y
    X(): x(0) { }                       // defines a constructor of X
};
int X::y = 1;                           // defines X::y
enum { up , down };                     // defines up and down
namespace N { int d; }                  // defines N and N::d
namespace N1 = N;                       // defines N1
X anX;                                  // defines anX


// all these are declarations
extern int a;                           // declares a
extern const int c;                     // declares c
int f(int);                             // declares f
struct S;                               // declares S
typedef int Int;                        // declares Int
extern X anotherX;                      // declares anotherX
using N::d;                             // declares N::d


// specific to C++11 - these are not from the standard
enum X : int;                           // declares X with int as the underlying type
using IntVector = std::vector<int>;     // declares IntVector as an alias to std::vector<int>
static_assert(X::y == 1, "Oops!");      // declares a static_assert which can render the program ill-formed or have no effect like an empty declaration, depending on the result of expr
template <class T> class C;             // declares template class C
;                                       // declares nothing

définition signifie fonction réelle écrite & amp; déclaration signifie simple déclarer une fonction par exemple

void  myfunction(); //this is simple declaration

et

void myfunction()
{
 some statement;    
}

c'est la définition de la fonction myfunction

Règle de base:

  • Une déclaration indique au compilateur comment interpréter les données de la variable en mémoire. Ceci est nécessaire pour chaque accès.

  • Une définition réserve la mémoire pour rendre la variable existante. Cela doit se produire exactement une fois avant le premier accès.

Déclaration:

int a; // this declares the variable 'a' which is of type 'int'

Ainsi, la déclaration associe la variable à un type.

Voici quelques exemples de déclaration.

int a;
float b;
double c;

Maintenant déclaration de fonction:

int fun(int a,int b); 

Notez le point-virgule à la fin de la fonction pour indiquer qu'il ne s'agit que d'une déclaration. Le compilateur sait que cette fonction sera définie dans le programme avec ce prototype. Maintenant, si le compilateur obtient un appel de fonction, quelque chose comme ceci

int b=fun(x,y,z);

Le compilateur générera une erreur en indiquant qu’une telle fonction n’existe pas. Parce qu’il n’a pas de prototype pour cette fonction.

Notez la différence entre deux programmes.

Programme 1

#include <stdio.h>
void print(int a)
{
     printf("%d",a);
}
main()
{
    print(5);
}

Dans ce cas, la fonction d'impression est également déclarée et définie. Puisque l'appel de fonction arrive après la définition. Voir maintenant le programme suivant.

Programme 2

 #include <stdio.h>
 void print(int a); // In this case this is essential
 main()
 {
    print(5);
 }
 void print(int a)
 {
     printf("%d",a);
 }

C’est essentiel car l’appel de la fonction précède la définition, le compilateur doit donc savoir s’il existe une telle fonction. Nous déclarons donc la fonction qui informera le compilateur.

Définition:

Cette partie de la définition d’une fonction s’appelle Définition. Il dit quoi faire dans la fonction.

void print(int a)
{
    printf("%d",a);
}

Maintenant avec les variables.

int a; //declaration
a=10; //definition 

Parfois, la déclaration et la définition sont regroupées dans une seule instruction comme celle-ci.

int a=10;

Pour comprendre les noms, concentrons-nous d'abord sur les verbes.

déclarer - annoncer officiellement; proclamer

définir - montrer ou décrire (quelqu'un ou quelque chose) clairement et complètement

Ainsi, lorsque vous déclarez quelque chose, vous dites simplement à ce que c'est .

// declaration
int sum(int, int);

Cette ligne déclare une fonction C appelée sum qui prend deux arguments de type int et renvoie un <=>. Cependant, vous ne pouvez pas encore l'utiliser.

Lorsque vous indiquez comment cela fonctionne réellement , c'est sa définition.

// definition
int sum(int x, int y)
{
    return x + y;
}

Pour comprendre la différence entre déclaration et définition, nous devons voir le code de l'assembly:

uint8_t   ui8 = 5;  |   movb    $0x5,-0x45(%rbp)
int         i = 5;  |   movl    $0x5,-0x3c(%rbp)
uint32_t ui32 = 5;  |   movl    $0x5,-0x38(%rbp)
uint64_t ui64 = 5;  |   movq    $0x5,-0x10(%rbp)
double   doub = 5;  |   movsd   0x328(%rip),%xmm0        # 0x400a20
                        movsd   %xmm0,-0x8(%rbp)

et ce n'est que définition:

ui8 = 5;   |   movb    $0x5,-0x45(%rbp)
i = 5;     |   movl    $0x5,-0x3c(%rbp)
ui32 = 5;  |   movl    $0x5,-0x38(%rbp)
ui64 = 5;  |   movq    $0x5,-0x10(%rbp)
doub = 5;  |   movsd   0x328(%rip),%xmm0        # 0x400a20
               movsd   %xmm0,-0x8(%rbp)

Comme vous pouvez le constater, rien ne change.

La déclaration est différente de la définition car elle donne des informations utilisées uniquement par le compilateur. Par exemple, uint8_t indique au compilateur d'utiliser la fonction asm movb.

Voir cela:

uint def;                  |  no instructions
printf("some stuff...");   |  [...] callq   0x400450 <printf@plt>
def=5;                     |  movb    $0x5,-0x45(%rbp)

La déclaration n'a pas d'instruction équivalente car ce n'est pas quelque chose à exécuter.

En outre, la déclaration indique au compilateur l'étendue de la variable.

Nous pouvons dire que la déclaration est une information utilisée par le compilateur pour établir l'utilisation correcte de la variable et la durée pendant laquelle de la mémoire appartient à une certaine variable.

Ne pourriez-vous pas énoncer dans les termes les plus généraux possibles qu’une déclaration est un identifiant dans lequel aucun stockage n’est alloué et qu’une définition attribue en fait un stockage à partir d’un identifiant déclaré?

Une idée intéressante: un modèle ne peut pas allouer de mémoire tant que la classe ou la fonction n’est pas liée aux informations de type. L'identifiant du modèle est-il une déclaration ou une définition? Il doit s'agir d'une déclaration car aucun stockage n'est alloué et vous ne faites que "prototyper" la classe ou la fonction de modèle.

Trouvez des réponses similaires ici: Questions d'entretien technique en C .

Une déclaration fournit un nom au programme. une définition fournit une description unique d'une entité (type, instance et fonction, par exemple) dans le programme. Les déclarations peuvent être répétées dans une portée donnée, cela introduit un nom dans une portée donnée.

Une déclaration est une définition sauf si:

  • Déclaration déclare une fonction sans spécifier son corps,
  • La déclaration contient un spécificateur externe et aucun initialiseur ou corps de fonction,
  • Déclaration est la déclaration d'un membre de données de classe statique sans définition de classe,
  • Déclaration est une définition de nom de classe,

Une définition est une déclaration sauf si:

  • Définition définit un membre de données de classe statique,
  • Définition définit une fonction membre non intégrée.

Cela va paraître vraiment ringard, mais c'est la meilleure façon dont j'ai pu garder les termes dans ma tête:

Déclaration: Imaginez que Thomas Jefferson prononce un discours ... & "JE DÉCLARE PAR LA PRÉSENTE QUE CE FOO EXISTE DANS CE CODE SOURCE !!! &";

Définition: imaginez un dictionnaire, vous recherchez Foo et ce qu’il signifie réellement.

Une déclaration présente un nom de symbole au compilateur. Une définition est une déclaration qui alloue de l’espace au symbole.

int f(int x); // function declaration (I know f exists)

int f(int x) { return 2*x; } // declaration and definition

Selon le manuel de la bibliothèque GNU C ( http: / /www.gnu.org/software/libc/manual/html_node/Header-Files.html )

  

En C, une déclaration fournit simplement des informations sur l’existence d’une fonction ou d’une variable et donne son type. Pour une déclaration de fonction, des informations sur les types de ses arguments peuvent également être fournies. Le but des déclarations est de permettre au compilateur de traiter correctement les références aux variables et fonctions déclarées. Une définition, en revanche, alloue effectivement le stockage d’une variable ou dit ce que fait une fonction.

Déclaration signifie donner le nom et le type à une variable (dans le cas d'une déclaration de variable), par exemple:

int i;

ou donner le nom, le type de retour et le type de paramètre (s) à une fonction sans corps (en cas de déclaration de fonction), par exemple:

int max(int, int);

alors que définition signifie affecter une valeur à une variable (dans le cas d'une définition de variable), par exemple:

i = 20;

ou fournir / ajouter un corps (fonctionnalité) à une fonction est appelée définition de fonction, par exemple:

int max(int a, int b)
{
   if(a>b)   return a;
   return b;  
}

plusieurs déclarations de temps et définitions peuvent être faites ensemble comme:

int i=20;

et:

int max(int a, int b)
{
    if(a>b)   return a;
    return b;    
} 

Dans les cas ci-dessus, nous définissons et déclarons les variables i et function max().

Le concept de Déclaration et de Définition constituera un écueil lorsque vous utiliserez la classe de stockage extern car votre définition sera à un autre emplacement et que vous déclarez la variable dans votre fichier de code local (page). Une différence entre C et C ++ réside dans le fait qu'en C, les déclarations sont faites normalement au début d'une page de fonction ou de code. En C ++, ce n'est pas comme ça. Vous pouvez déclarer à l'endroit de votre choix.

Mon exemple préféré est " int Num = 5 " Ici, votre variable est 1. définie comme int 2. déclarée comme Num et 3. instanciée avec une valeur de cinq. Nous

  • Définit le type d'un objet, qui peut être intégré ou être une classe ou une structure.
  • Déclarez le nom d'un objet. Ainsi, tout ce qui porte un nom a été déclaré et comprend des variables, des fonctions, etc.

Une classe ou une structure vous permet de modifier la manière dont les objets seront définis lorsqu’elle sera utilisée ultérieurement. Par exemple

  • On peut déclarer une variable ou un tableau hétérogène qui ne sont pas spécifiquement définis.
  • En utilisant un décalage en C ++, vous pouvez définir un objet qui n'a pas de nom déclaré.

Lorsque nous apprenons à programmer, ces deux termes sont souvent confondus parce que nous faisons souvent les deux en même temps.

Etapes d'une génération d'exécutable:

  

(1) pré-processeur - > (2) traducteur / compilateur - & Gt; (3) éditeur de liens

À l'étape 2 (traducteur / compilateur), les instructions de déclaration de notre code indiquent au compilateur que nous allons utiliser ces éléments à l'avenir et que vous pourrez trouver une définition plus tard, ce qui signifie:

  Le

traducteur veille à ce que: qu'est-ce que c'est? signifie déclaration

et (3) l'étape (l'éditeur de liens) a besoin d'une définition pour lier les éléments

  

L'éditeur de liens veille à ce que: où est quoi? signifie définition

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top