What is the difference between a definition and a declaration?

Viewed 427679

The meaning of both eludes me.

27 Answers

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

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.

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.

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.

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

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]

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.

Adding definition and declaration examples from the C++ standard document(from the section 3.1 Declarations and definitions)

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

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 d

Declaration says "this thing exists somewhere"

int sampleFunc(); // function
extern int car;  // variable

Definition says "this thing exists here; make memory for it"

int sampleFunc() {} // function
int car; // variable

Initialization is optional at the point of definition for objects, and says "here is the initial value for this thing":

int car = 0; // variable
Related