Categories
c c++-faq terminology

What is the difference between a definition and a declaration?

987

The meaning of both eludes me.

10

  • 13

    Frankly, I had a lot of trouble learning which was which, so I didn’t find the names obvious. I had no problem with the meanings, just which names to associate with the meanings.

    Sep 11, 2009 at 14:10

  • 1

    We’ve been over this in exhaustive detail: stackoverflow.com/questions/671925/…

    Sep 11, 2009 at 14:17

  • 7

    Still, it’s not a duplicate question, since this asks about C/C++, whereas that other question asked about all languages, or none, in general. It just has duplicate answers (since in that other question, some answers chose to ignore all language except C and/or C++).

    Sep 11, 2009 at 14:23

  • 7

    @DavidThornley I use this trick: a definition gives a finer description of a given variable or function. To remember this, I recall that the middle of the word “definition” has a resemblance to the word “finer”. 🙂

    Jul 27, 2012 at 6:39


  • 2

    @MarcoLeogrande: Or “definite”!

    Apr 14, 2013 at 17:41

990

A declaration introduces an identifier and describes its type, be it a type, object, or function. A declaration is what the compiler needs to accept references to that identifier. These are declarations:

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 actually instantiates/implements this identifier. It’s what the linker needs in order to link references to those entities. These are definitions corresponding to the above declarations:

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

A definition can be used in the place of a declaration.

An identifier can be declared as often as you want. Thus, the following is legal in C and 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);

However, it must be defined exactly once. If you forget to define something that’s been declared and referenced somewhere, then the linker doesn’t know what to link references to and complains about a missing symbols. If you define something more than once, then the linker doesn’t know which of the definitions to link references to and complains about duplicated symbols.


Since the debate what is a class declaration vs. a class definition in C++ keeps coming up (in answers and comments to other questions) , I’ll paste a quote from the C++ standard here.
At 3.1/2, C++03 says:

A declaration is a definition unless it […] is a class name declaration […].

3.1/3 then gives a few examples. Amongst them:

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

To sum it up: The C++ standard considers struct x; to be a declaration and struct x {}; a definition. (In other words, “forward declaration” a misnomer, since there are no other forms of class declarations in C++.)

Thanks to litb (Johannes Schaub) who dug out the actual chapter and verse in one of his answers.

30

  • 2

    @unknown: either your compiler is broken of you have mis-copied sbi’s code. For example, 6.7.2(2) in N1124: “All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.”

    Sep 11, 2009 at 13:09

  • 4

    @Brian: “extern int i;” says that i is an int somewhere, don’t worry about it. “int i;” means that i is an int, and its address and scope is determined here.

    Sep 11, 2009 at 14:05

  • 13

    @Brian: You’re wrong. extern int i is a declaration, since it just introduces/specifies i. You can have as many extern int i in each compilation unit as you want. int i, however, is a definition. It denotes the space for the integer to be in this translation unit and advices the linker to link all references to i against this entity. If you have more or less than exactly one of these definitions, the linker will complain.

    – sbi

    Sep 11, 2009 at 14:09

  • 5

    @Brian int i; in file/global scope or function scope is a definition both in C and C++. In C because it allocates storage, and in C++ because it does not have the extern specifier or a linkage-specification. These amount to the same thing, which is what sbi says: in both cases this declaration specifies the object to which all references to “i” in that scope must be linked.

    Sep 11, 2009 at 14:14

  • 4

    @unknown, beware you cannot redeclare members in class scope: struct A { double f(int, double); double f(int, double); }; invalid, of course. It’s allowed elsewhere though. There are some places where you can declare things, but not define, too: void f() { void g(); } valid, but not the following: void f() { void g() { } };. What is a definition and what a declaration has subtle rules when it comes to templates – beware! +1 for a good answer though.

    Sep 11, 2009 at 16:54

184

From the C++ standard section 3.1:

A declaration introduces names into a translation unit or redeclares names introduced by previous
declarations. A declaration specifies the interpretation and attributes of these names.

The next paragraph states (emphasis mine) that a declaration is a definition unless…

… it declares a function without specifying the function’s body:

void sqrt(double);  // declares sqrt

… it declares a static member within a class definition:

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

… it declares a class name:

class Y;

… it contains the extern keyword without an initializer or function body:

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

… or is a typedef or using statement.

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

Now for the big reason why it’s important to understand the difference between a declaration and definition: the One Definition Rule. From section 3.2.1 of the C++ standard:

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

4

  • 1

    “declares a static member within a class definition” – This is true even if the static member is initialised, correct? Can we make the example struct x {static int b = 3; };?

    Mar 4, 2014 at 13:27

  • 1

    @RJFalconer You’re correct; initialization does not necessarily turn a declaration into a definition (contrary to what one might expect; certainly I found this surprising). Your modification to the example is actually illegal unless b is also declared const. See stackoverflow.com/a/3536513/1858225 and daniweb.com/software-development/cpp/threads/140739/… .

    Aug 14, 2014 at 17:08


  • 2

    This is interesting to me. According to your answer, it seems that in C++, a declaration is also a definition (with exceptions), whereas in the C standard it is phrased from the other perspective (C99, section 6.7, Declarations): “A definition of an identifier is a declaration for that identifier that: [followed by criteria for different cases]”. Different ways to look at it, I suppose. 🙂

    Oct 7, 2014 at 13:52

  • 1

    Declaration is for the compiler to accept a name(to tell the compiler that the name is legal, the name is introduced with intention not a typo). Definition is where a name and its content is associated. The definition is used by the linker to link a name reference to the content of the name.

    Feb 11, 2016 at 14:45

157

Declaration: “Somewhere, there exists a foo.”

Definition: “…and here it is!”

1

  • 4

    Declaration is for the compiler to accept a name(to tell the compiler that the name is legal, the name is introduced with intention not a typo). Definition is where a name and its content is associated. The definition is used by the linker to link a name reference to the content of the name.

    Feb 11, 2016 at 14:41