1059 Stimmen

Was ist der Unterschied zwischen einer Definition und einer Erklärung?

Die Bedeutung von beidem entzieht sich mir.

20 Stimmen

Um ehrlich zu sein, hatte ich große Schwierigkeiten, herauszufinden, wer wer ist, und ich fand die Namen nicht offensichtlich. Ich hatte kein Problem mit den Bedeutungen, sondern nur damit, welche Namen ich mit den Bedeutungen in Verbindung bringen konnte.

2 Stimmen

Wir haben das schon ausführlich besprochen: stackoverflow.com/questions/671925/

7 Stimmen

Dennoch ist es keine doppelte Frage, da diese Frage sich auf C/C++ bezieht, während die andere Frage sich auf alle oder keine Sprachen im Allgemeinen bezieht. Es gibt nur doppelte Antworten (da bei der anderen Frage einige Antworten alle Sprachen außer C und/oder C++ ignorierten).

1062voto

sbi Punkte 211669

A Erklärung führt einen Bezeichner ein und beschreibt seinen Typ, sei es ein Typ, ein Objekt oder eine Funktion. Eine Deklaration ist was der Compiler braucht um Verweise auf diesen Bezeichner zu akzeptieren. Dies sind Deklarationen:

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

A Definition diesen Bezeichner tatsächlich instanziiert/implementiert. Es ist was der Linker braucht um Verweise auf diese Entitäten zu verknüpfen. Dies sind die Definitionen, die den obigen Erklärungen entsprechen:

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

Eine Definition kann anstelle einer Erklärung verwendet werden.

Ein Bezeichner kann sein erklärt so oft wie Sie wollen. So ist das Folgende in C und C++ legal:

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

Es muss jedoch sein definiert genau einmal. Wenn Sie vergessen, etwas zu definieren, das bereits irgendwo deklariert und referenziert wurde, dann weiß der Linker nicht, worauf er verweisen soll und beschwert sich über fehlende Symbole. Wenn Sie etwas mehr als einmal definieren, dann weiß der Linker nicht die der Definitionen, um Verweise zu verknüpfen, und beschwert sich über doppelte Symbole.


Seit der Debatte darüber, was eine Klasse ist Erklärung vs. eine Klasse Definition in C++ immer wieder auftaucht (in Antworten und Kommentaren zu anderen Fragen), füge ich hier ein Zitat aus dem C++-Standard ein.
Bei 3.1/2, sagt C++03:

Eine Deklaration ist eine Definition, es sei denn, es handelt sich [...] um eine Klassendeklaration [...].

3.1/3 führt dann einige Beispiele an. Darunter:

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

Zusammengefasst: Der C++-Standard berücksichtigt struct x; zu sein Erklärung y struct x {}; a Definition . (Mit anderen Worten, "Vorwärtsmeldung" eine falsche Bezeichnung , da es in C++ keine anderen Formen von Klassendeklarationen gibt).

Dank an litb (Johannes Schaub) der in einer seiner Antworten das eigentliche Kapitel und den Vers ausgrub.

190voto

Michael Kristofik Punkte 32950

Aus dem C++ Standard Abschnitt 3.1:

A Erklärung fügt Namen in eine Übersetzungseinheit ein oder deklariert Namen neu, die durch vorherige Deklarationen eingeführt wurden. Eine Deklaration spezifiziert die Interpretation und die Attribute dieser Namen.

Im nächsten Absatz heißt es (Hervorhebung von mir), dass eine Erklärung ist eine Definition es sei denn...

... es deklariert eine Funktion, ohne den Körper der Funktion zu spezifizieren:

void sqrt(double);  // declares sqrt

... es deklariert ein statisches Mitglied innerhalb einer Klassendefinition:

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

... es deklariert einen Klassennamen:

class Y;

... es enthält die extern Schlüsselwort ohne einen Initialisierer oder einen Funktionskörper:

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

... oder ist ein typedef o using Erklärung.

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

Jetzt kommt der Hauptgrund, warum es wichtig ist, den Unterschied zwischen einer Erklärung und einer Definition zu verstehen: Die Die Regel der einen Definition . Aus Abschnitt 3.2.1 des C++-Standards:

Keine Übersetzungseinheit darf mehr als eine Definition einer Variablen, Funktion, eines Klassentyps, eines Aufzählungstyps oder einer Vorlage enthalten.

169voto

plinth Punkte 46829

Erklärung: "Irgendwo gibt es ein Foo".

Definition: "...und hier ist es!"

54voto

Es gibt interessante Randfälle in C++ (einige davon auch in C). Betrachten Sie

T t;

Das kann eine Definition oder eine Erklärung sein, je nachdem, welche Art von T ist:

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".

In C++ gibt es bei der Verwendung von Schablonen einen weiteren Grenzfall.

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

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

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

Die letzte Erklärung war pas eine Definition. Es ist die Deklaration einer expliziten Spezialisierung des statischen Mitglieds von X<bool> . Es sagt dem Compiler: "Wenn es zur Instanziierung kommt X<bool>::member , dann instanziieren Sie nicht die Definition des Mitglieds aus der primären Vorlage, sondern verwenden Sie die Definition, die Sie an anderer Stelle gefunden haben". Um es zu einer Definition zu machen, müssen Sie einen Initialisierer angeben

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

37voto

KV Prajapati Punkte 91877

Erklärung

Deklarationen teilen dem Compiler mit, dass ein Programmelement oder ein Name existiert. A Deklaration fügt einen oder mehrere Namen in ein Programm ein. Deklarationen können mehr als einmal in einem Programm vorkommen. Daher können Klassen, Strukturen, Aufzählungstypen und andere benutzerdefinierte Typen können für jede jede Kompiliereinheit deklariert werden.

Definition

Definitionen geben an, welchen Code oder welche Daten der Name beschreibt. Ein Name muss sein deklariert werden, bevor er verwendet werden kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X