The const issue
Bastien JAUNY

Bastien JAUNY @bjauny

About: Software Engineer with 10 years of experience, I have a soft spot for open-source software and DevOps culture.

Location:
Nantes, FRANCE
Joined:
Oct 4, 2019

The const issue

Publish Date: Oct 17 '19
6 3

TLDR: always put const AFTER the element you want to specify as constant

We all love const variables and parameters. They are, well, constant. You're sure they won't be changed by a side-effect of your code (or someone else's).
What you usually see in C++ is something like:

const int myVar(42);

This is pretty clear, right? myVar is stores an integer, 42 in this case, and this value won't change until we get out of the current scope. So if we put something like:

const int myVar(42);
myVar++;

your compiler will yell at you with something like error: increment of read-only variable ‘myVar’.

So far so good. But I once again stumbled across an issue using const that I, even with my 10+ years of experience, still haven't stuck in my head (but I hope that writing this down will help so I'll guess I should share it).

Let's say you want to declare a constant pointer to an integer. The no-brainer line of code that gets out is:

const int *myVarPtr;

Following the same logic as before, if I try to modify it:

int myVar(42);
const int *myVarPtr;
myVarPtr++;

the compiler doesn't complain! And it's normal because, if you stick to its definition, const applies to the element to its left, unless it's the first element. Then it applies to its right.
So what we declared earlier was actually a non-const pointer to a const integer. The original goal would be achieved with this code:

int * const myVarPtr;

I hate exceptions. This is the typical case where the exception makes the concept confusing. Now I just make sure I'm never in this case.

If you have only one thing to learn from this article it would be this: always put const AFTER the element you want to specify as constant.

Comments 3 total

  • Loki Le DEV
    Loki Le DEVOct 21, 2019

    I totally agree, by placing the const on the right side we can read from right to left:

    int foo;        // integer
    int const foo;  // const integer
    int* foo;       // pointer to integer
    int const* foo; // pointer to constant integer
    int& foo;       // reference to int
    int const& foo; // reference to constant int
    int const* const foo; // constant pointer to constant int
    int const& const foo; // constant reference to constant int    
    
    Enter fullscreen mode Exit fullscreen mode
    • Pierre Gradot
      Pierre GradotMay 26, 2021

      int const& const foo; doesn't compile in C++.

      It is impossible make a reference "points" to another variable.

      A 'const reference' means that the reference considers it "points" a const object.

  • 🏎️Tim Beaudet🚀
    🏎️Tim Beaudet🚀Nov 16, 2019

    I disagree, while it does read slightly better right-to-left, which is required for determining what is const, it isn't clear. For instance in your example, you did not modify myVar, (assuming that pointer was set to the address of myVar) - but you modified the *. To me it reads much cleaner as:

    const int* myVarPtr

    assuming you don't want to change the value, which is 99% of the time - generally we don't care if the pointer gets modified, but the contents it points to... now that is important.

    In the 1% of the time that both, or just the pointer, is important to be const, then the imo ugly:

    const int* const myVarPtr;
    int* const myPtr;

    Will stop and make the reader / maintainer look twice. If the const was ALWAYS on the right,

    int const value;
    int* const valuePtr;

    it is easy, very easy to slip up in maintaining or accidental writing of a const pointer to a non const value, when it should have been a pointer (const or not) to a const value.

Add comment