Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constant pointer variables in C++ [duplicate]

Possible Duplicate:
What is the difference between const int*, const int * const, and int const *?

I know two variations of pointer variables in C++.

Say I have

mystruct{
    int num;
}

Variation 1:

const mystruct* m1; means the member variables in m1 can not be altered, for instance, m1->num = 2 would produce an error.

Variation 2:

mystruct *const m2 = m1; means once m2 is set to point to m1, an error would be produced if you subsequently set m2 =m3.

However, there seems to be a third variation, that I am not certain the property of:

Variation 3:

mystruct const * m3;

What does this mean?

like image 725
Haoest Avatar asked May 18 '11 05:05

Haoest


2 Answers

Variant 3 is exactly the same as variant 1. The const applies to whatever is to the left of it. If there is nothing (first variant), it applies to the thing that is right of it. Also, you're missing one variation.

const int* pi1; // varyable pointer to constant int
int const* pi2; // again - varyable pointer to constant int
int* const pi3; // constant pointer to varyable int
// you're missign the next
int const * const pi4; // constant pointer to constant int

I personally prefer the second version to the first, as that is what the compiler parses and when you read the type from right to left, it is clearer. :) Also, that's what I did in the comments - intuitive, isn't it?

Oh, yeah, all of the above also applies to volatile. Together they're counted as cv-qualifiers (cv = const volatile).

And as a last point, for future references: There's always cdecl.org. As long as you don't mix in C++ types, you can find out the meaning of potentially any declaration. Edit: Interestingly enough, it chokes on int const i;. I think I'll need to research if the variable ordering of cv-qualifiers was introduced in C++.

like image 155
Xeo Avatar answered Oct 06 '22 05:10

Xeo


Declarations in C++ consist of two parts:

decl-specifier-seq init-declarator-list ;

The decl-specifier-seq is a sequence of keywords, such as volatile, const, mutable typedef etc... and a type. The order of these specifiers doesn't matter, so you can write:

int typedef unsigned A;
int const B = 1;

and they are the same as

typedef unsigned int A;
const int B = 1;

init-declarator-list is the comma separated sequence of entities you declare. Each of these entities gets the type of the decl-specifier-seq with some modifiers applied to it:

int typedef *A, B[10], *const C;

Here A gets the type 'pointer to int', B is an array of ints and C is a constant pointer to int.

As you see in your case:

mystruct const *m2 = m1;

the const is a part of the decl-specifier-seq, so it modifies mystruct to be const, not the pointer itself.

like image 43
Yakov Galka Avatar answered Oct 06 '22 03:10

Yakov Galka