What distinguishes the declaration, the definition and the initialization of a variable?
Asked Answered
N

4

104

After reading the question, I know the differences between declaration and definition. So does it mean definition equals declaration plus initialization?

Network answered 28/4, 2014 at 15:48 Comment(2)
Initialization is for variables. Definition can apply also for functions, where you define the body.Benham
So do you mean for a variable, it's right.Network
S
126

Declaration

Declaration, generally, refers to the introduction of a new name in the program. For example, you can declare a new function by describing it's "signature":

void xyz();

or declare an incomplete type:

class klass;
struct ztruct;

and last but not least, to declare an object:

int x;

It is described, in the C++ standard, at §3.1/1 as:

A declaration (Clause 7) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.

Definition

A definition is a definition of a previously declared name (or it can be both definition and declaration). For example:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

Specifically the C++ standard defines it, at §3.1/1, as:

A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function- body, it declares a static data member in a class definition (9.2, 9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), it is a template-parameter (14.1), it is a parameter-declaration (8.3.5) in a function declarator that is not the declarator of a function-definition, or it is a typedef declaration (7.1.3), an alias-declaration (7.1.3), a using-declaration (7.3.3), a static_assert-declaration (Clause 7), an attribute- declaration (Clause 7), an empty-declaration (Clause 7), or a using-directive (7.3.4).

Initialization

Initialization refers to the "assignment" of a value, at construction time. For a generic object of type T, it's often in the form:

T x = i;

but in C++ it can be:

T x(i);

or even:

T x {i};

with C++11.

Conclusion

So does it mean definition equals declaration plus initialization?

It depends. On what you are talking about. If you are talking about an object, for example:

int x;

This is a definition without initialization. The following, instead, is a definition with initialization:

int x = 0;

In certain context, it doesn't make sense to talk about "initialization", "definition" and "declaration". If you are talking about a function, for example, initialization does not mean much.

So, the answer is no: definition does not automatically mean declaration plus initialization.

Shiloh answered 28/4, 2014 at 16:3 Comment(5)
Not quite: int x; is a definition as well as a declaration.Maidinwaiting
@Angew, thanks, I've added a more complete definition.Shiloh
I think the question that OP mentioned in his post answers definition and declaration pretty well. But the original question was So does it mean definition equals declaration plus initialization.Aneroidograph
@Tahlil, added a conclusion. Thanks for making me notice.Shiloh
@Network I think (please someone correct me if Im wrong so I learn) 'extern int x' makes it just a declaration, meaning that definition is found elsewhere. Whilst 'int x' actually defines it albeit it gets appointed with random garbage value, unless you initialize it specifically like 'int x = 5'.Stepfather
G
62

Declaration says "this thing exists somewhere":

int foo();       // function
extern int bar;  // variable
struct T
{
   static int baz;  // static member variable
};

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

int foo() {}     // function
int bar;         // variable
int T::baz;      // static member variable

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

int bar = 0;     // variable
int T::baz = 42; // static member variable

Sometimes it's possible at the point of declaration instead:

struct T
{
   static int baz = 42;
};

…but that's getting into more complex features.

Gabey answered 28/4, 2014 at 16:25 Comment(5)
Very well explained, except that initialization is a bit more complex than that. (This wouldn't be C++ if it were that simple.) Initialization includes things like the zero initialization of variables with static lifetime, and default constructors, as well as what you show. (And to add to the confusion: in C, initialization can be the first time the variable is assigned to; e.g. in statements like "taking the value of an uninitialized variable". It wouldn't surprise me if some of this also slipped into C++.)Aliment
Oh, and there are also special cases where C++ permits the specification of the initialization in a declaration.Aliment
@JamesKanze: Decided to keep it super simple for these purposesGabey
This doesn't make sense, static member variables allocate memory.Rematch
I'm no expert (btw, baz needs to be const or constexpr, otherwise it won't compile), but I think the compiler allows initialization without definition because that value can be used in expressions that can be evaluated at compile time. So if you have something like int x = T::baz;, the compiler just does search-and-replace on it and the expression becomes int x = 42;. If you push baz onto a function call, foo(T::baz);, then you should allocate memory for it via a definition.Cyclostyle
U
9

For C, at least, per C11 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, is the (only) declaration of the identifier;

  • for a typedef name, is the first (or only) declaration of the identifier.

Per C11 6.7.9.8-10:

An initializer specifies the initial value stored in an object ... if an object that has automatic storage is not initialized explicitly, its value is indeterminate.

So, broadly speaking, a declaration introduces an identifier and provides information about it. For a variable, a definition is a declaration which allocates storage for that variable.

Initialization is the specification of the initial value to be stored in an object, which is not necessarily the same as the first time you explicitly assign a value to it. A variable has a value when you define it, whether or not you explicitly give it a value. If you don't explicitly give it a value, and the variable has automatic storage, it will have an initial value, but that value will be indeterminate. If it has static storage, it will be initialized implicitly depending on the type (e.g. pointer types get initialized to null pointers, arithmetic types get initialized to zero, and so on).

So, if you define an automatic variable without specifying an initial value for it, such as:

int myfunc(void) {
    int myvar;
    ...

You are defining it (and therefore also declaring it, since definitions are declarations), but not initializing it. Therefore, definition does not equal declaration plus initialization.

Unlucky answered 28/4, 2014 at 16:15 Comment(3)
In C++, initialization is significantly different. (C also has the equivalent of zero initialization of objects with static lifetime.)Aliment
@JamesKanze: Yes, unfortunately this question is tagged with both C and C++, which isn't very helpful on those points where they differ.Unlucky
Quite. For the compatible types, the intent (at least originally) in C++ was that they behave the same as in C; in fact, I think they do still behave the same in all of the cases where the languages are themselves compatible. But the wording used to define this behavior is quite different.Aliment
A
1

"So does it mean definition equals declaration plus initialization."

Not necessarily, your declaration might be without any variable being initialized like:

 void helloWorld(); //declaration or Prototype.

 void helloWorld()
 {
    std::cout << "Hello World\n";
 } 
Attorney answered 28/4, 2014 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.