7

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?

Community
  • 1
  • 1
Haoest
  • 13,610
  • 29
  • 89
  • 105
  • 1
    Note that in version 1 the meaning is that members of the pointer object cannot be changed **using that m1 pointer**, not that they cannot be changed in general. In other words nothing is said about the object being pointed to is constant... the word const is still **relative to the pointer**, with the meaning of "can't be used for writing". – 6502 May 18 '11 at 05:40
  • Voting to close since this is an exact duplicate save for the use of `mystruct` instead of `int`. :) – Xeo May 18 '11 at 05:52

2 Answers2

8

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++.

Xeo
  • 129,499
  • 52
  • 291
  • 397
1

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.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220