Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const before or const after?

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.


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.


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

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;

??