84

For example, is

int const x = 3;

valid code?

If so, does it mean the same as

const int x = 3;

?

user383352
  • 5,033
  • 4
  • 25
  • 20

8 Answers8

150

They are both valid code and they are both equivalent. For a pointer type though they are both valid code but not equivalent.

Declares 2 ints which are constant:

int const x1 = 3;
const int x2 = 3;

Declares a pointer whose data cannot be changed through the pointer:

const int *p = &someInt;

Declares a pointer who cannot be changed to point to something else:

int * const p = &someInt;
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 4
    And ` const int * const p = &someInt;` would give you a pointer that cannot be changed to a value that cannot be changed, if I'm not mistaken. – JAB Jul 14 '10 at 14:51
  • @JAB: Yes it will give you a pointer that can't be changed in addition to having data that can't be changed inside the pointer through that pointer. – Brian R. Bondy Jul 14 '10 at 14:54
  • 91
    The pattern here becomes apparent if the definitions are **read in reverse**. For example: `[const int *]` = a pointer (`*`) to an `int` that is `const`. `[int * const]` = a `const` pointer (`*`) to an `int`. – stakx - no longer contributing Jul 14 '10 at 14:54
  • 5
    C syntax reads crappy no matter what you do. It wasn't designed to produce readable sources. You just have to learn the rules. – T.E.D. Jul 14 '10 at 15:06
  • 5
    @ T.E.D. : Not quite. Just get into the habit to write `const` always *after* the thing it applies to, and you're done. (Always-trailing is the only style that could be applied *consistently*.) – DevSolar Jul 14 '10 at 15:31
  • 4
    You should also include 'int const *' and just for a laugh 'int const * const' – Martin York Jul 14 '10 at 16:21
  • @Brian R. Bondy - They can both be quite useful at times though. In particular I end up using `int const *` (a read-only view of some other variable or area of memory) in systems programming all the time. – T.E.D. Jul 14 '10 at 21:13
  • It should also be noted that const int *p = &someInt, simply bars that pointer from modifying the int but the int value itself can still be changed. If someInt was declared int someInt = 0, and somewhere after p was declared, there can be code that says someInt = 5, it would compile and run without problems. – Yogurt Aug 09 '13 at 21:21
  • 2
    **-1** This contrast is misleading. It works the same for pointer types if you put the `const` before or after the type. Moving it past the `*` is another thing altogether. – Galik Aug 03 '16 at 09:37
41

Yes, they are the same. The rule in C++ is essentially that const applies to the type to its left. However, there's an exception that if you put it on the extreme left of the declaration, it applies to the first part of the type.

For example in int const * you have a pointer to a constant integer. In int * const you have a constant pointer to an integer. You can extrapolate this to pointer to pointers, and the English may get confusing but the principle is the same.

For another dicussion on the merits of doing one over the other, see my question on the subject. If you are curious why most folks use the exception, this FAQ entry of Stroustrup's may be helpful.

jmbpiano
  • 561
  • 3
  • 19
T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • 3
    Exactly what I was thinking. `const int x` is the exceptional form. `int const x` fits the same pattern as `int * const x`. If you need a constant pointer to a constant int, I usually write it as `int const * const` for consistency rather than `const int * const`. – Cogwheel Jul 14 '10 at 15:04
  • @Cogwheel - Precisely. Once you realise the "normal" form of putting the `const` to the extreme left is actually making use of an exceptional case, the question arises as to which way actually makes the code clearer in the long run. Hence my question http://stackoverflow.com/questions/988069/in-c-is-const-after-type-id-acceptable – T.E.D. Jul 14 '10 at 15:10
  • @T.E.D. **The rule in C++ is essentially that const applies to the type to its left.** Is there any citation for this by known programming gurus or just kind of understood thing. Also in the "const int * p1". There is nothing to the left of const. How to apply the rule in this scenario. – Talespin_Kit Apr 28 '17 at 16:24
20

Yes, that is exactly the same. However, there is difference in pointers. I mean:

int a;

// these two are the same: pointed value mustn't be changed
// i.e. pointer to const value
const int * p1 = &a;
int const * p2 = &a;

// something else -- pointed value may be modified, but pointer cannot point
// anywhere else i.e. const pointer to value
int * const p3 = &a;

// ...and combination of the two above
// i.e. const pointer to const value
const int * const p4 = &a;
T.E.D.
  • 44,016
  • 10
  • 73
  • 134
Archie
  • 6,391
  • 4
  • 36
  • 44
15

From "Effective C++" Item 21

char *p              = "data"; //non-const pointer, non-const data
const char *p        = "data"; //non-const pointer, const data
char * const p       = "data"; //const pointer, non-const data
const char * const p = "data"; //const pointer, const data

const pointer: pointed value may be modified, but pointer cannot point
anywhere else 
Liu Boyu
  • 13
  • 3
Yuan
  • 2,690
  • 4
  • 26
  • 38
4

It is the same in meaning and validity.

As far as I know, const only get complex whenever it involves pointer.

int const * x;
int * const x; 

are different.

int const * x;
const int * x; 

are same.

ttchong
  • 307
  • 2
  • 9
0

I found that if always write const in right, it will becoming easier to read a complex pointer type, for fun.

For example:

// Just append const or pointer to
int x; // data
int const cx; // const data
int *px; // pointer to data
int const *pcx; //pointer to const data
int * const cpx; // const pointer to data
int const * const * * const cppcpcx; // const pointer to (pointer to (const pointer to const data))
Puelloc
  • 101
  • 3
0

I have an idea how to interpret (non)const pointers and data. Split it with *.

Data type Star sign Pointer type Combine Data Pointer
int * p int *p non-const non-const
const int * p const int *p const non-const
int * const p int *const p non-const const
const int * const p const int *const p const const
0
// 1.

int x1 = 1;
int x2 = 2;

const int* p = &x1;
//*p = 3;          // variable data is CAN NOT BE changed through pointer
p = &x2;           // pointer CAN POINT to other variable

cout << *p << endl;   // OUTPUT: 2


 
// 2.

int y1 = 1;
int y2 = 2;

int* const t = &y1;
*t = 3;            // variable data is CAN BE changed through pointer
//t = &y2;         // pointer CAN NOT POINT to other variable

cout << *t<<endl;   // OUTPUT: 3
Zrn-dev
  • 99
  • 5