20.1.  Declarations and Definitions

[ fromfile: scopestorage.xml id: iddefdecl ]

Any identifier must be declared or defined before it is used. Declaring a name means telling the compiler what type to associate with that name.

Defining an object, or variable, means allocating space and (optionally) assigning an initial value. For example,

    double x, y, z;
    char* p;
    int i = 0;
    QString message("Hello");

Defining a function means completely describing its behavior in a block of C++ statements. For example,

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

Defining a class means specifying its structure in a sequence of declarations of function and data members, as you can see in Example 20.1. Among other things, a class definition tells the compiler how much memory is required for an object of that class.

Example 20.1. src/early-examples/decldef/point.h

class Point {                           1
 public:
    Point(int x, int y, int z);         2
    int distance(Point other);          3
    double norm() const {               4         
        return distance(Point(0,0,0));
    } 
 private:
    int m_Xcoord, m_Ycoord, m_Zcoord;   5
};

1

Class head.

2

A constructor declaration.

3

A function declaration.

4

Declaration and definition.

5

Data member declaration.


Example 20.2 contains some declarations that are not definitions.

Example 20.2. src/early-examples/decldef/point.cpp

extern int step;       1
class Map;             2
int max(int a, int b); 3

1

An object (variable) declaration.

2

A (forward) class declaration.

3

A global (non member) function declaration.


Each declaration that is not a definition conveys an implicit promise to the compiler (which will be enforced by the linker) that the declared name will be defined in an appropriate location somewhere else in the program.

Each definition is a declaration. There can be only one definition of any name in any scope, but there can be multiple declarations.

[Note] Note

Variable initialization might seem to be "optional" in C++. But initialization of variables always takes place – regardless of whether it is specified. A statement of the form

TypeT var;

results in default initialization of the variable var. Default initialization means that a value is supplied by the compiler. For simple types (e.g., int, double, char) the default value is undefined; i.e., that value might be zero and it might be some random garbage that happens to be in the memory assigned to var. For class objects, the value is determined by the default constructor, if one exists – otherwise the compiler reports an error. Consequently, it is strongly recommended that a well-chosen initial value be provided for all variable definitions; otherwise invalid results or strange runtime errors can occur that might be difficult to locate. It is worth repeating this rule: All objects and variables should be properly initialized at (or immediately after) creation time.