17

This is a general programming question. I'm learning about C++ and I've learned that any const variables, ie: const int i, or int *const ptr, have to be initialized right away.

This is also the underlying reason that references to addresses must be initialized right away, because the addresses are const.

But I can't find the reason why this must be done / why this rule is imposed.

Can anyone explain this for me please?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Lebowski156
  • 951
  • 5
  • 11
  • 34

4 Answers4

26

Because there is no way you can initialize it, or assigned with a value, later on.

const int size; //no initialization (error)

size = 100; //error - you cannot assign a const variable.

Now if a variable which is neither having any meaningful value, nor are you allowed to make it to have value later on because it is a const variable, then what is the point of such a variable? It is completely useless.

However, this is true for only built-in and POD types:

struct A{}; //POD type
struct B{ B(){} }; //Non POD type because it has user-defined constructor!

const int i; //error - built-in type
const A a;   //error - POD type
const B b;   //ok -    Non POD type

//likewise
const std::string s; //ok - std::string is a non-POD
const std::vector<std::string> v; //ok - std::vector is a non-POD

Actually a NON-POD type cannot remain uninitialized, because the default constructor will be called, and the object would get initialized.


Now consider this struct,

struct C
{
   const int i;
   C() {}
};

C is definitely a non-POD type, because it has user-defined constructor. Also note that in the constructor, it doesn't initialize i which is int, declared as const. Because of this uninitialized const i, the following would give error:

const C c; //error - 

One might think the error is because of const in the above declaration of variable c. But that is short-sightedness and is not true. Even if you remove const, it would give error:

C c; //error - same error

The error is because of C::i which is declared const but has not been initialized.

Demo : http://ideone.com/NJT8L


This analysis also demonstrates that built-in types do not get initialized automatically even if they're members of non-POD types. This is true of non-POD class types as well.

And the syntax to default initialization for built-in types (and POD types) is this:

struct C
{
    const int i;
    C() : i() {} //note the syntax - it is called member-initialization list
};

Now this is allowed :

C x; //ok
const C y; //ok

Demo : http://ideone.com/84vD9


As for what makes a struct/class POD, see this topic:

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Doesn't const int size; initialize size using int's default constructor (ie to 0) though? – Lebowski156 Dec 09 '11 at 02:43
  • Btw, I'm giving your answer the check mark once the timer lets me. In writing 'int i;', i is initialized to 0 with the default constructor. Why doesn't it use the default constructor with const? Maybe this should be a separate question ... – Lebowski156 Dec 09 '11 at 02:51
  • @Lebowski156: `int i` doesn't initialize to `0` (if it is a local variable), the spec doesn't guarantee that. However, if you write `int i` at namespace level then it is *statically* initialized to 0. But the moment you make it a const variable, you will give error. That is how the language specification have defined the behavior. – Nawaz Dec 09 '11 at 02:54
  • "_This analysis also demonstrate that built-in types do get initialize automatically even if they're member of non-POD types._" ??? – curiousguy Dec 09 '11 at 03:15
  • @curiousguy: It was a typo. There should be a **no**. I just corrected it. – Nawaz Dec 09 '11 at 03:16
  • @Nawaz: C() : i() {} If I am not wrong variable i will be value initialized that turns to be 0 initialization here at the end. right? – Destructor Jun 23 '15 at 13:20
  • @PravasiMeet: `i()` causes `i` to be value-initialized. Since this is built-in type, value-initialization means zero-initialization. So yes, you're right. – Nawaz Jun 23 '15 at 14:57
5

Because if you could assign to them later, they wouldn't be "const".

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 3
    I think "later" is a bit misleading here. It seems like the important property of a `const` variable is that it can only be assigned *once*. So if it can be assigned after an assignment has occurred, then it wouldn't be `const`. But nothing about that requires that the assignment be made at declaration time. So I think what the OP is asking is, why does the initial assignment have to happen as part of the declaration? – aroth Dec 09 '11 at 02:46
  • 5
    @aroth: To be pedantic, a `const` variable can *never* be assigned. And to answer your point; you're conflating declaration and definition. – Oliver Charlesworth Dec 09 '11 at 02:47
  • 2
    And as an interesting side-note (in the spirit of this being a general programming question), Java does allow `final` variables to be assigned after the initial declaration. But only once. – aroth Dec 09 '11 at 02:54
  • @aroth "_the important property of a const variable_" define "const variable" – curiousguy Dec 09 '11 at 03:17
0

Assignment to a const variable in the program is not allowed because then you may change its value which is obviously wrong!!!!

Hence, you need to initialize them..

hope it helps

bhuwansahni
  • 1,834
  • 1
  • 14
  • 20
0

When a variable is declared as const it means that , variable is read-only ,and cant be changed .so in order to make a variable read only it should be initialized at the time it is declared.

For better understanding of variables have a look at following program

Every process consists of basically 4 portions of address space that are accessible to the process when it is running

Text - This portion contains the actual m/c instructions to be executed. On many Operating Systems this is set to read only, so that the process can't modify its instructions. This allows multiple instances of the program to share the single copy of the text.

Data - This portion contains the program's data part. It furthere divided into

1) Initialized Read Only Data - This contains the data elements that are initialized by the program and they are read only during the execution of the process.

2) Initialized Read Write Data - This contains the data elements that are initialized by the program and will be modified in the course of process execution.

3)Uninitalized Data - This contains the elements are not initialized by the program and are set 0 before the processes executes. These can also be modified and referred as BSS(Block Started Symbol). The adv of such elements are, system doesn't have to allocate space in the program file for this area, b'coz it is initialized to 0 by OS before the process begins to execute.

Stack - This portion is used for local variables, stack frames

Heap - This portion contains the dynamically allocated memory

int abc = 1;                            ---->   Initialized Read-Write Data
char *str;                              ---->   BSS
const int i = 10;                       ----->  Initialized Read-Only Data

main()
{
    int ii,a=1,b=2,c;                            ----->  Local Variables on 
Stack

    char *ptr;
    ptr = malloc(4);                     ------> Allocated Memory in Heap

     c= a+b;                             ------> Text

}

Data, store data Text, store code

There are 3 (main?) segments/sections of the file produced by a linker. text - program text (and apparently const char arrays. maybe other 'const' arrays, since those can not be changed anyway). I am not 100% sure about the array part, maybe someone will correct me.

data - initialized global data. see examples below. bss - uninitialized global data. Here are some examples

int x = 1;    /* goes into data */
int y;        /* goes into bss  */
const int z = 1;/* goes into text */

this, we've seen go into 'text', since can't be changed anyway,but can be protected

Imposter
  • 2,666
  • 1
  • 21
  • 31