926

The meaning of both eludes me.

MD XF
  • 7,062
  • 7
  • 34
  • 64
Maciek
  • 17,805
  • 17
  • 59
  • 85
  • 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. – David Thornley Sep 11 '09 at 14:10
  • 1
    We've been over this in exhaustive detail: http://stackoverflow.com/questions/671925/is-there-a-strict-definition-for-the-words-define-declare-and-assign – dmckee --- ex-moderator kitten Sep 11 '09 at 14:17
  • 6
    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++). – Steve Jessop Sep 11 '09 at 14:23
  • 5
    @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". :) – Marco Leogrande Jul 27 '12 at 06:39
  • 1
    @MarcoLeogrande: Or "definite"! – Lightness Races in Orbit Apr 14 '13 at 17:41
  • 1
    A much more interesting question is "difference between a declaration and a _prototype_": http://stackoverflow.com/questions/5481579/whats-the-difference-between-function-prototype-and-declaration – Mooing Duck Jun 26 '13 at 19:51
  • 1
    Here's a nice article that explains how the extern keyword and memory allocation relates to declarations / definitions: http://www.dreamincode.net/forums/topic/171468-declarations-vs-definitions/ – Griffin Jul 18 '13 at 20:41
  • 1
    this may help http://www.cprogramming.com/declare_vs_define.html – barlop Sep 19 '15 at 12:48
  • If you have trouble remembering which is which, realize that the terms are in alphabetical order - Declaration, Definition, Reference. Generally that is the order they should appear. – SuwaneeCreek Aug 10 '17 at 16:05
  • Possible duplicate of [What exactly are C++ definitions, declarations and assignments?](https://stackoverflow.com/questions/671925/what-exactly-are-c-definitions-declarations-and-assignments) – TylerH Dec 26 '18 at 22:35

25 Answers25

919

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.

Community
  • 1
  • 1
sbi
  • 204,536
  • 44
  • 236
  • 426
  • 1
    Is that multiple-declaration legal according to the STANDARD, or your compiler, or what? I cannot do that multiple times in the same scope. – San Jacinto Sep 11 '09 at 12:56
  • 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." – Steve Jessop Sep 11 '09 at 13:09
  • 1
    @unknown: or possibly it's issuing a warning, which you're promoting to an error. – Steve Jessop Sep 11 '09 at 13:10
  • 1
    yes, it was a bad compiler. i tried it again on GCC and it workd. hint: don't use imagecraft's c compiler. – San Jacinto Sep 11 '09 at 13:13
  • 1
    "If you define something more than once, then the linker doesn't know which of the definitions to link references to". Although you can get away with that if the definitions are in different translation units, are equivalent, and and have appropriate modifiers telling the linker it's OK to fold them (principally "inline") – Steve Jessop Sep 11 '09 at 13:13
  • 1
    @onebyone: Yes, there are exceptions, notably inlined functions that the compiler won't inline for whatever reason. However, I didn't want to add exceptions to the answer if the questioner doesn't know the difference between declaration and definition. I was quite surprised about all the misleading answers (that have since disappeared). I hadn't thought such misconceptions are so wide-spread. – sbi Sep 11 '09 at 13:39
  • 1
    I would say that "int i;" is also a declaration, and you never actually DEFINE an int variable... but other than that, +1 – Brian Postow Sep 11 '09 at 13:59
  • 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. – David Thornley Sep 11 '09 at 14:05
  • 12
    @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 '09 at 14:09
  • 4
    @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. – Steve Jessop Sep 11 '09 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. – Johannes Schaub - litb Sep 11 '09 at 16:54
  • 1
    My main issue with this answer is that the initial explanation that a definition is what the linker needs is unhelpful in the case of a class definition. The linker never needs to link to a class itself (which like a typedef is really of declarative nature only); it may however link to a (static) class instance, to class methods, or to the class vtable, for _none_ of which the class definition is used. But the compiler does not to see more than a class declaration for many things. So calling it a class _definition_ is really just a matter of convention, not justified by the given explanation. – Marc van Leeuwen May 26 '14 at 22:44
  • 2
    "A definition can be used in the place of a declaration." This may be incorrect. If is only legal if no duplicated definition will be introduced. – Thomson Aug 01 '14 at 06:12
  • 1
    @Thomson: "An identifier can be declared as often as you want. [...] ___However, it must be defined exactly once.___" – sbi Aug 02 '14 at 07:21
  • 1
    @sbi thanks for the clarification. I know the statement I quoted is correct with some condition. Just the condition is a little far from the quoted sentence. – Thomson Aug 02 '14 at 14:10
  • Quoting from this page: http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html "The following are declared as functions and may also be defined as macros. Function prototypes must be provided for use with an ISO C compiler." What is meant by 'Function prototypes must be provided for use with an ISO C compiler.' ? – Koray Tugay May 21 '15 at 15:53
  • quoting from your answer: "then the linker doesn't know what to link references to" do you mean "then the linker doesn't know what the link references to"? – Koray Tugay May 21 '15 at 15:55
  • @Koray: I didn't even mention C's macros, because they are so strange breasts. Basically, you cannot declare a macro, you can only define it. But the preprocessor is not a real compiler, but a simple text processor anyway... In K&R C, functions didn't declare their parameters, so all you needed as a declaration was their name. In ISO C, you need proper declarations. I suppose this is what the comment you quoted refers to. And, no, I meant that sentence to be the way I wrote it. – sbi May 23 '15 at 07:00
  • @sbi: why http://ideone.com/wIBBTi fails in compilation. there can be as many as I want declarations of identifier but must be exactly 1 definition as I think. I haven't defined & called any of the function. Why an error in the program? what is the reason? – Destructor Aug 25 '15 at 08:34
  • @JohannesSchaub-litb: you says that double f(int, double); double f(int, double); } is allowed elsewhere but not in class scope. then why it isn't allowed at global scope. Why http://ideone.com/wIBBTi fails in compilation? – Destructor Aug 25 '15 at 08:35
  • 1
    @Pravasi: You declare two functions which have the same name, but differ in their return types. In C++, this is not allowed, you can only overload functions when their parameters differ. – sbi Aug 25 '15 at 13:39
  • @sbi I wanted to edit your answer, but I'm not confident enough to. I've tried putting extern before a struct or class and it seems to be in the category with the functions, ie., adding extern doesn't seem to make a difference. I'm talking about the bit: // no extern allowed for type declarations - at the top of your answer. – Zebrafish Dec 24 '16 at 01:04
  • does int x; implicitly initiate x to zero whereas extern int x does not? – YuZ Feb 28 '17 at 09:10
  • @user3921720: Nope. – sbi Feb 28 '17 at 17:55
  • then why is int x; a definition and extern int x a declaration? – YuZ Mar 02 '17 at 16:15
  • Because one defines a variable `x` of type `int`, while the other declares `x` to be a variable of type `int` which is to be defined elsewhere? *shrug* I really don't know what to say here. (Have you tried reading my answer? It explains this.) – sbi Mar 27 '17 at 14:28
  • May mislead newbie: `int x` also includes a declaration. Because `definition` is a `subset` of `declaration` – 陳 力 Dec 05 '17 at 10:42
  • @czxyl: _"A definition can be used in the place of a declaration."_ – sbi Dec 09 '17 at 09:43
  • Would be great if someone could extend this answer to include the **meaning of initialization**. Such as https://stackoverflow.com/q/23345554/6060872 – rehctawrats Feb 08 '18 at 08:46
  • @sbi, _A definition can be used in the place of a declaration_, does not seem to take into account that a non constant static data member must be initialized out of line, so its declaration in the class cannot be substituted by a defition. – Enlico May 17 '20 at 16:09
  • @EnricoMariaDeAngelis: Yeah, I didn't cover classes at all. Read Johannes' comment further up on this. – sbi Jul 11 '20 at 20:59
177

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.

Felipe Augusto
  • 5,811
  • 7
  • 29
  • 60
Michael Kristofik
  • 31,476
  • 15
  • 72
  • 121
  • "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; };`? – RJFalconer Mar 04 '14 at 13:27
  • @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 http://stackoverflow.com/a/3536513/1858225 and http://www.daniweb.com/software-development/cpp/threads/140739/taking-an-address . – Kyle Strand Aug 14 '14 at 17:08
  • 1
    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. :) – Victor Zamanian Oct 07 '14 at 13:52
  • 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. – Gab是好人 Feb 11 '16 at 14:45
142

Declaration: "Somewhere, there exists a foo."

Definition: "...and here it is!"

plinth
  • 45,549
  • 9
  • 75
  • 118
  • 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. – Gab是好人 Feb 11 '16 at 14:41
49

There are interesting edge cases in C++ (some of them in C too). Consider

T t;

That can be a definition or a declaration, depending on what type T is:

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++, when using templates, there is another edge case.

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

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

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

The last declaration was not a definition. It's the declaration of an explicit specialization of the static member of X<bool>. It tells the compiler: "If it comes to instantiating X<bool>::member, then don't instantiate the definition of the member from the primary template, but use the definition found elsewhere". To make it a definition, you have to supply an initializer

template<>
int X<bool>::member = 1; // definition, belongs into a .cpp file.
Johannes Schaub - litb
  • 466,055
  • 116
  • 851
  • 1,175
35

Declaration

Declarations tell the compiler that a program element or name exists. A declaration introduces one or more names into a program. Declarations can occur more than once in a program. Therefore, classes, structures, enumerated types, and other user-defined types can be declared for each compilation unit.

Definition

Definitions specify what code or data the name describes. A name must be declared before it can be used.

kv-prajapati
  • 90,019
  • 18
  • 141
  • 178
  • Um, isn't it that you can even _define_ classes and enums in each compilation unit? At least I put class _definitions_ into my headers and include them all over. Er, `class foo {};` _is_ a class _definition_, isn't it? – sbi Sep 11 '09 at 13:03
  • 1
    Yes. However, "class foo;" is a declaration. It tells the compiler that foo is a class. "class foo {};" is a definition. It tells the compiler exactly what sort of class foo is. – David Thornley Sep 11 '09 at 14:01
  • @David: Right. And since we all put class and enum _definitions_ into our headers files, it's class and enum _definitions_, not declarations, that can be repeated for each compilation unit. That makes adatapost's answer, um, _misleading_. – sbi Sep 11 '09 at 14:17
  • 1
    The exception are class member names which may be used before they're declared. – Johannes Schaub - litb Sep 11 '09 at 16:56
  • @litb: I don't think that's true: `class blah { foo bar(); typedef int foo; };` gives a compile-time error. What you mean is that member function _definitions_ are, even when they are defined _within_ the class' definition, parsed as if they were defined right _behind_ the class' definition. – sbi Sep 11 '09 at 17:41
  • 1
    Yeah, that's what i meant. So you can do the following: struct foo { void b() { f(); } void f(); }, f is visible even though not declared yet. The following works too: struct foo { void b(int = bar()); typedef int bar; };. It's visible before its declaration in "all function bodies, default arguments, constructor ctor-initializers". Not in the return type :( – Johannes Schaub - litb Sep 11 '09 at 18:00
  • 1
    @litb: It isn't visible before it's declaration, it's only that the _use_ of the identifier is moved behind the declaration. Yeah, I know, the effect is the same for many cases. But not for all cases, which is why I think we should use the precise explanation. -- Oops, wait. It is visible in default arguments? Well, that surely wreaks havoc with my understanding. Dammit! – sbi Sep 11 '09 at 19:27
22

From the C99 standard, 6.7(5):

A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:

  • for an object, causes storage to be reserved for that object;
  • for a function, includes the function body;
  • for an enumeration constant or typedef name, is the (only) declaration of the identifier.

From the C++ standard, 3.1(2):

A declaration is a definition unless it declares a function without specifying the function's body, it contains the extern specifier or a linkage-specification and neither an initializer nor a function-body, it declares a static data member in a class declaration, it is a class name declaration, or it is a typedef declaration, a using-declaration, or a using-directive.

Then there are some examples.

So interestingly (or not, but I'm slightly surprised by it), typedef int myint; is a definition in C99, but only a declaration in C++.

Steve Jessop
  • 257,525
  • 32
  • 431
  • 672
  • @onebyone: Regarding the `typedef`, wouldn't that mean that it could be repeated in C++, but not in C99? – sbi Sep 11 '09 at 14:20
  • That's what surprised me, and as far as a single translation unit is concerned, yes there is that difference. But clearly a typedef can be repeated in C99 in different translation units. C doesn't have an explicit "one definition rule" like C++, so the rules it does have just allow it. C++ chose to change it to a declaration, but also the one definition rule lists what kinds of things it applies to, and typedefs isn't one of them. So repeats would be allowed in C++ under the ODR as it's worded, even if a typedef was a definition. Seems unnecessarily picky. – Steve Jessop Sep 11 '09 at 14:35
  • ... but I'd guess that list in the ODR actually lists all the things it's possible to have definitions of. If so, then the list is actually redundant, and is just there to be helpful. – Steve Jessop Sep 11 '09 at 14:35
  • What does the std's ODR definition say about class definitions? They _have_ to be repeated. – sbi Sep 11 '09 at 15:03
  • I suspect the rationale for it is because a typedef declares just a name, without producing something beyond (like, a type, object or something). So it's just a declaration, much like a using-declaration. – Johannes Schaub - litb Sep 11 '09 at 20:52
  • However, note that you *can* have multiple definitions of the same namespace, although it sounds odd: `namespace A { } namespace A { }` – Johannes Schaub - litb Sep 11 '09 at 20:55
  • 2
    @sbi: ODR says "(1) No translation unit shall contain more than one definition of any ... class type" and "(5) There can be more than one definition of a class type ... in a program provided that each definition appears in a different translation unit" and then some extra requirements which amount to "the definitions are the same". – Steve Jessop Sep 12 '09 at 12:21
  • @litb: yep, namespaces aren't mentioned in the first clause of the ODR. Indeed I often use that in header files, where I have groups of functions I close and re-open the namespaces between them, so that each "section" of the header file stands alone. – Steve Jessop Sep 12 '09 at 12:24
  • @onebyone: I always thought ODR deals with definitions _across_ translation units. I'm surprised it's limited to TUs. – sbi Sep 12 '09 at 13:35
  • @sbi: it deal with both. Clause 1 is about what can't be duplicated in a single translation unit. Clause 5 lists some things which can be duplicated in the program provided they're in different units. There are other wondrous clauses too large to fit in this margin^Hcomment. – Steve Jessop Sep 12 '09 at 13:52
  • @onebyone: I tried to dig through the Holy Paper several times, but my understanding of English seems to simply lack too much in order to understand standardeze. But then again, maybe I'm just not the kind of person who reads legaleze, not matter what language it comes in... – sbi Sep 12 '09 at 21:58
  • @sbi: I've certainly never read the standard cover-to-cover, but the index is pretty good :-) – Steve Jessop Sep 13 '09 at 10:32
  • 1
    @SteveJessop: update your answer according to C11 standard because as you know C11 allows repeated typedef also. – Destructor Feb 03 '16 at 16:40
18

From wiki.answers.com:

The term declaration means (in C) that you are telling the compiler about type, size and in case of function declaration, type and size of its parameters of any variable, or user defined type or function in your program. No space is reserved in memory for any variable in case of declaration. However compiler knows how much space to reserve in case a variable of this type is created.

for example, following are all declarations:

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

Definition on the other hand means that in additions to all the things that declaration does, space is also reserved in memory. You can say "DEFINITION = DECLARATION + SPACE RESERVATION" following are examples of definition:

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

see Answers.

Kate Gregory
  • 18,565
  • 8
  • 53
  • 85
Marcin Gil
  • 62,506
  • 8
  • 57
  • 60
  • 3
    This, too, is wrong (although much closer than the others): `struct foo {};` is a __definition__, not a declaration. A declaration of `foo` would be `struct foo;`. From that, the compiler doesn't know how much space to reserve for `foo` objects. – sbi Sep 11 '09 at 12:37
  • sbi, my answer reflects what you are saying. in your example, you define a foo as an empty structure. I fail to understand how our examples are technically different. – San Jacinto Sep 11 '09 at 12:43
  • 1
    @Marcin: sbi is saying that "compiler knows how much space to reserve in case a variable of this type is created" is not always true. `struct foo;` is a declaration, but it does not tell the compiler the size of foo. I'd add that `struct _tagExample { int a; int b; };` is a definition. So in this context it is misleading to call it a declaration. Of course it is one, since all definitions are declarations, but you seem to be suggesting that it is not a definition. It is a definition, of _tagExample. – Steve Jessop Sep 11 '09 at 13:01
  • 1
    @Marcin Gil: Which means that "Answers" wiki is not always accurate. I have to downvote for misinformation here. – David Thornley Sep 11 '09 at 14:07
  • So we have an answer copied straight from MSDN (adatapost's) and one from answers.com and both are misleading or even plain wrong. What do we learn from this? – sbi Sep 11 '09 at 14:14
  • 1
    We learn that what adatapost quoted is true but does not (IMO) really answer the question. What Marcin quoted is false. Quoting the standards is true and answers the question, but is very difficult to make head or tail of. – Steve Jessop Sep 11 '09 at 14:18
  • @onebyone: A _very_ nice summary indeed! (I, however, had reinforced what I learned as a student and later tried to hammer into _my_ students: Copying without thinking might lead to a disaster. `:^>`) – sbi Sep 11 '09 at 14:23
  • 1
    @David Thornley - not a problem :) This is what this site is about. *We* select and verify info. – Marcin Gil Sep 11 '09 at 18:15
  • It should be noted that `struct foo { int a; };` in C is not a definition. C doesn't know struct definitions. In reverse, a typedef is a definition in C. – Johannes Schaub - litb Sep 11 '09 at 18:25
14

C++11 Update

Since I don't see an answer pertinent to C++11 here's one.

A declaration is a definition unless it declares a/n:

  • opaque enum - enum X : int;
  • template parameter - T in template<typename T> class MyArray;
  • parameter declaration - x and y in int add(int x, int y);
  • alias declaration - using IntVector = std::vector<int>;
  • static assert declaration - static_assert(sizeof(int) == 4, "Yikes!")
  • attribute declaration (implementation-defined)
  • empty declaration ;

Additional clauses inherited from C++03 by the above list:

  • function declaration - add in int add(int x, int y);
  • extern specifier containing declaration or a linkage specifier - extern int a; or extern "C" { ... };
  • static data member in a class - x in class C { static int x; };
  • class/struct declaration - struct Point;
  • typedef declaration - typedef int Int;
  • using declaration - using std::cout;
  • using directive - using namespace NS;

A template-declaration is a declaration. A template-declaration is also a definition if its declaration defines a function, a class, or a static data member.

Examples from the standard which differentiates between declaration and definition that I found helpful in understanding the nuances between them:

// 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
Community
  • 1
  • 1
legends2k
  • 27,643
  • 22
  • 108
  • 196
6

Definition :

extern int a;      // Declaration 
int a;             // Definition
a = 10             // Initialization
int b = 10;        // Definition & Initialization

Definition associates the variable with a type and allocates memory, whereas declaration just specifies the type but doesn't allocate memory. Declaration is more useful when you want to refer the variable before definition.

*Don't confuse definition with initialization. Both are different, initialization gives value to the variable. See the above example.

Following are some examples of definition.

int a;
float b;
double c;

Now function declaration :

int fun(int a,int b); 

Note the semicolon at the end of function so it says it is only a declaration. Compiler knows that somewhere in the program that function will be defined with that prototype. Now if the compiler gets a function call something like this

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

Compiler will throw an error saying that there is no such function. Because it doesn't has any prototype for that function.

Note the difference between two programs.

Program 1

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

In this, print function is declared and defined as well. Since function call is coming after the definition. Now see the next program.

Program 2

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

It is essential because function call precedes definition so compiler must know whether there is any such function. So we declare the function which will inform the compiler.

Definition :

This part of defining a function is called Definition. It says what to do inside the function.

void print(int a)
{
    printf("%d",a);
}
SRIDHARAN
  • 911
  • 1
  • 13
  • 27
  • 3
    `int a; //declaration; a=10; //definition` This is completely wrong. When talking about automatic storage duration objects (objects declared inside a function definition that are not declared with another storage class specifier like extern) these are **always** definitions. – Joey Pabalinas Feb 11 '18 at 18:06
  • The main difference to grasp is that a declaration is saying "a thing exists somewhere that has these traits (type etc.)," whereas a definition is saying "I am declaring a thing with these traits, and I am also instantiating it here as well." Since you can't forward declare automatic storage duration objects like that, they will always be definitions. – Joey Pabalinas Feb 11 '18 at 18:06
  • Except for maybe some weird typedef corner cases that I always forget about, a rule of thumb is that **All definitions are declarations.** Think about it; when you are instantiating something, you also need to tell the compiler that that thing exists and what its traits are right? – Joey Pabalinas Feb 11 '18 at 18:07
  • Updated the answer as per your first comment. however I don't agree with this comment "when you are instantiating something, you also need to tell the compiler that that thing exists". We don't always specify the type of lhs when instantiating. Ex: a =10. We are not specifying any "traits" of a here. – SRIDHARAN Jan 31 '20 at 17:32
6

To understand the nouns, let's focus on the verbs first.

declare - to announce officially; proclaim

define - to show or describe (someone or something) clearly and completely

So, when you declare something, you just tell what it is.

// declaration
int sum(int, int);

This line declares a C function called sum that takes two arguments of type int and returns an int. However, you can't use it yet.

When you provide how it actually works, that's the definition of it.

// definition
int sum(int x, int y)
{
    return x + y;
}
Karoly Nyisztor
  • 2,949
  • 1
  • 22
  • 20
4

Rule of thumb:

  • A declaration tells the compiler how to interpret the variable's data in memory. This is needed for every access.

  • A definition reserves the memory to make the variable existing. This has to happen exactly once before first access.

bjhend
  • 1,354
  • 8
  • 21
4

definition means actual function written & declaration means simple declare function for e.g.

void  myfunction(); //this is simple declaration

and

void myfunction()
{
 some statement;    
}

this is definition of function myfunction

Flexo
  • 82,006
  • 22
  • 174
  • 256
3

To understand the difference between declaration and definition we need to see the assembly code:

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)

and this is only definition:

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)

As you can see nothing change.

Declaration is different from definition because it gives information used only by the compiler. For example uint8_t tell the compiler to use asm function movb.

See that:

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

Declaration haven't an equivalent instruction because it is no something to be executed.

Furthermore declaration tells the compiler the scope of the variable.

We can say that declaration is an information used by the compiler to establish the correct use of the variable and for how long some memory belongs to certain variable.

princio
  • 91
  • 6
2

Couldnt you state in the most general terms possible, that a declaration is an identifier in which no storage is allocated and a definition actually allocates storage from a declared identifier?

One interesting thought - a template cannot allocate storage until the class or function is linked with the type information. So is the template identifier a declaration or definition? It should be a declaration since no storage is allocated, and you are simply 'prototyping' the template class or function.

  • 1
    Your definition isn't per se wrong, but "storage definition" always seems awkward when it comes to function definitions. Regarding templates: This `template struct foo;` is a template _declaration_, and so is this `template void f();`. Template definitions mirror class/function definitions in the same way. (Note that a _template name_ is not a _type_ or _function name_. One place where you can see this is when you cannot pass a template as another template's type parameter. If you want to pass templates instead of types, you need template template parameters.) – sbi Sep 11 '09 at 15:09
  • Agreed that 'storage definition' is awkward, especially regarding function definitions. The declaration is int foo() and definition is int foo() {//some code here..}. I usually need to wrap my small brain with concepts I am familiar - 'storage' is one such way to keep it straight to me at least... :) –  Sep 11 '09 at 15:59
2

Find similar answers here: Technical Interview Questions in C.

A declaration provides a name to the program; a definition provides a unique description of an entity (e.g. type, instance, and function) within the program. Declarations can be repeated in a given scope, it introduces a name in a given scope.

A declaration is a definition unless:

  • Declaration declares a function without specifying its body,
  • Declaration contains an extern specifier and no initializer or function body,
  • Declaration is the declaration of a static class data member without a class definition,
  • Declaration is a class name definition,

A definition is a declaration unless:

  • Definition defines a static class data member,
  • Definition defines a non-inline member function.
Felipe Augusto
  • 5,811
  • 7
  • 29
  • 60
Santosh
  • 1,114
  • 2
  • 14
  • 30
1

This is going to sound really cheesy, but it's the best way I've been able to keep the terms straight in my head:

Declaration: Picture Thomas Jefferson giving a speech... "I HEREBY DECLARE THAT THIS FOO EXISTS IN THIS SOURCE CODE!!!"

Definition: picture a dictionary, you are looking up Foo and what it actually means.

It'sPete
  • 4,728
  • 5
  • 33
  • 64
1

A declaration presents a symbol name to the compiler. A definition is a declaration that allocates space for the symbol.

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

int f(int x) { return 2*x; } // declaration and definition
hdante
  • 6,100
  • 1
  • 27
  • 34
1

According to the GNU C library manual (http://www.gnu.org/software/libc/manual/html_node/Header-Files.html)

In C, a declaration merely provides information that a function or variable exists and gives its type. For a function declaration, information about the types of its arguments might be provided as well. The purpose of declarations is to allow the compiler to correctly process references to the declared variables and functions. A definition, on the other hand, actually allocates storage for a variable or says what a function does.

LinuxBabe
  • 309
  • 2
  • 6
0

The concept of Declaration and Definition will form a pitfall when you are using the extern storage class because your definition will be in some other location and you are declaring the variable in your local code file (page). One difference between C and C++ is that in C you the declarations are done normally at the beginning of a function or code page. In C++ it's not like that. You can declare at a place of your choice.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
achoora
  • 1,190
  • 12
  • 28
0

My favorite example is "int Num = 5" here your variable is 1. defined as int 2. declared as Num and 3. instantiated with a value of five. We

  • Define the type of an object, which may be built-in or a class or struct.
  • Declare the name of an object, so anything with a name has been declared which includes Variables, Funtions, etc.

A class or struct allows you to change how objects will be defined when it is later used. For example

  • One may declare a heterogeneous variable or array which are not specifically defined.
  • Using an offset in C++ you may define an object which does not have a declared name.

When we learn programming these two terms are often confused because we often do both at the same time.

Jason K.
  • 377
  • 3
  • 12
  • I do not understand why so many people upvoted sbi's answer. I did upvote the answer by bjhend, which was quite good, concise, accurate and much more timely than mine. I was sad to see that I was the first person to do so in 4 years. – Jason K. Oct 09 '16 at 23:25
0

Stages of an executable generation:

(1) pre-processor -> (2) translator/compiler -> (3) linker

In stage 2 (translator/compiler), declaration statements in our code tell to the compiler that these things we are going to use in future and you can find definition later, meaning is :

translator make sure that : what is what ? means declaration

and (3) stage (linker) needs definition to bind the things

Linker make sure that : where is what ? means definition

humble_wolf
  • 952
  • 11
  • 20
Jeet Parikh
  • 185
  • 1
  • 8
0

There are some very clear definitions sprinkled throughout K&R (2nd edition); it helps to put them in one place and read them as one:

"Definition" refers to the place where the variable is created or assigned storage; "declaration" refers to the places where the nature of the variable is stated but no storage is allocated. [p. 33]

...

It is important to distinguish between the declaration of an external variable and its definition. A declaration announces the properties of a variable (primarily its type); a definition also causes storage to be set aside. If the lines

int sp;
double val[MAXVAL]

appear outside of any function, they define the external variables sp and val, cause storage to be set aside, and also serve as the declaration for the rest of that source file.

On the other hand, the lines

extern int sp;
extern double val[];

declare for the rest of the source file that sp is an int and that val is a double array (whose size is determined elsewhere), but they do not create the variables or reserve storage for them.

There must be only one definition of an external variable among all the files that make up the source program. ... Array sizes must be specified with the definition, but are optional with an extern declaration. [pp. 80-81]

...

Declarations specify the interpretation given to each identifier; they do not necessarily reserve storage associated with the identifier. Declarations that reserve storage are called definitions. [p. 210]

Brad Solomon
  • 29,156
  • 20
  • 104
  • 175
0

The declaration is when a primitive or object reference variable or method is created without assigning value or object. int a; final int a;

The definition means assigning the value or object respectively int a =10;

Initialization means allocating memory for a respective variable or object.

0

Declaration of a variable is for informing to the compiler the following information: name of the variable, type of value it holds and the initial value if any it takes. i.e., declaration gives details about the properties of a variable. Whereas, Definition of a variable says where the variable gets stored. i.e., memory for the variable is allocated during the definition of the variable.

sun1211
  • 81
  • 1
  • 3
-1

Declaration means give name and type to a variable (in case of variable declaration), eg:

int i;

or give name,return type and parameter(s) type to a function without body(in case of function declaration), eg:

int max(int, int);

whereas definition means assign value to a variable (in case of variable definition), eg:

i = 20;

or provide/add body(functionality) to a function is called function definition, eg:

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

many time declaration and definition can be done together as:

int i=20;

and:

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

In above cases we define and declare variable i and function max().

Felipe Augusto
  • 5,811
  • 7
  • 29
  • 60
Puneet Purohit
  • 1,101
  • 5
  • 20
  • 39