Const before or const after?

C++CSyntaxConstants

C++ Problem Overview


To start you probably know that const can be used to make either an object's data or a pointer not modifiable or both.

const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer

However you can also use the syntax:

Object const *obj; // same as const Object* obj;

The only thing that seems to matter is which side of the asterisk you put the const keyword. Personally I prefer to put const on the left of the type to specify it's data is not modifiable as I find it reads better in my left-to-right mindset but which syntax came first?

More importantly why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?

Edit:

So it sounds like this was an arbitrary decision when the standard for how compilers should interpret things was drafted long before I was born. Since const is applied to what is to the left of the keyword (by default?) I guess they figured there was no harm in adding "shortcuts" to apply keywords and type qualifiers in other ways at least until such a time as the declaration changes by parsing a * or & ...

This was the case in C as well then I'm assuming?

C++ Solutions


Solution 1 - C++

>why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?

Essentially, the reason that the position of const within specifiers prior to an asterisk does not matter is that the C grammar was defined that way by Kernighan and Ritchie.

The reason they defined the grammar in this way was likely that their C compiler parsed input from left-to-right and finished processing each token as it consumed that. Consuming the * token changes the state of the current declaration to a pointer type. Encountering const after * means the const qualifier is applied to a pointer declaration; encountering it prior to the * means the qualifier is applied to the data pointed to.

Because the semantic meaning does not change if the const qualifier appears before or after the type specifiers, it is accepted either way.

A similar sort of case arises when declaring function pointers, where:

  • void * function1(void) declares a function which returns void *,

  • void (* function2)(void) declares a function pointer to a function which returns void.

Again the thing to notice is that the language syntax supports a left-to-right parser.

Solution 2 - C++

The rule is:

> const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.

I prefer using const on the right of the thing to be const just because it is the "original" way const is defined.

But I think this is a very subjective point of view.

Solution 3 - C++

I prefer the second syntax. It helps me keep track of 'what' is constant by reading the type declaration from right to left:

Object * const obj;        // read right-to-left:  const pointer to Object
Object const * obj;        // read right-to-left:  pointer to const Object
Object const * const obj;  // read right-to-left:  const pointer to const Object

Solution 4 - C++

The order of the keywords in a declaration isn't all that fixed. There are many alternatives to "the one true order". Like this

int long const long unsigned volatile i = 0;

or should it be

volatile unsigned long long int const i = 0;

??

Solution 5 - C++

The first rule is to use whichever format your local coding standards requires. After that: putting the const in front leads to no end of confusion when typedefs are involved, e.g.:

typedef int* IntPtr;
const IntPtr p1;   // same as int* const p1;

If your coding standard allows typedef's of pointers, then it really should insist on putting the const after the type. In every case but when applied to the type, const must follow what it applies to, so coherence also argues in favor of the const after. But local coding guidelines trump all of these; the difference isn't normally important enough to go back and change all of the existing code.

Solution 6 - C++

There are historical reasons that either left or right is acceptable. Stroustrup had added const to C++ by 1983, but it didn't make it to C until C89/C90.

In C++ there's a good reason to always use const on the right. You'll be consistent everywhere because const member functions must be declared this way:

int getInt() const;

Solution 7 - C++

C uses a right-to-left syntax. Just read the declarations from right to left:

int var = 0;

// one is a pointer to a const int
int const * one = &var; 
// two is a pointer to an int const (same as "const int")
const int * two = &var; 

// three is a constant pointer to an int
int * const three = &var;

The first thing left to the "const" is affected by it.

For more fun read this guide: http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html

Solution 8 - C++

With

using P_Int = int *;

P_Int const a = nullptr;
int * const b = nullptr;

const P_Int c = nullptr;
const int * d = nullptr;

the variables a and b are the same type as each other but, somewhat confusingly, the variables c and d are not the same type as each other. My preference is for the first scenario, without the confusion: have const on the right of the type. N.B. it is the pointer that is const with a, b, and c; but the int is const with d.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAJG85View Question on Stackoverflow
Solution 1 - C++Heath HunnicuttView Answer on Stackoverflow
Solution 2 - C++horstforstView Answer on Stackoverflow
Solution 3 - C++Matt DavisView Answer on Stackoverflow
Solution 4 - C++Bo PerssonView Answer on Stackoverflow
Solution 5 - C++James KanzeView Answer on Stackoverflow
Solution 6 - C++Nick WestgateView Answer on Stackoverflow
Solution 7 - C++MacMarkView Answer on Stackoverflow
Solution 8 - C++LeeView Answer on Stackoverflow