Search

6.10 — Pointers and const

Pointing to const variables

So far, all of the pointers you’ve seen are non-const pointers to non-const values:

However, what happens if value is const?

The above snippet won’t compile -- we can’t set a non-const pointer to a const variable. This makes sense: a const variable is one whose value can not be changed. Hypothetically, if we could set a non-const pointer to a const value, then we would be able to dereference the non-const pointer and change the value. That would violate the intention of const.

Pointer to const value

A pointer to a const value is a (non-const) pointer that points to a constant value.

To declare a pointer to a const value, use the const keyword before the data type:

In the above example, ptr points to a const int.

So far, so good, right? Now consider the following example:

A pointer to a constant variable can point to a non-constant variable (such as variable value in the example above). Think of it this way: a pointer to a constant variable treats the variable as constant when it is accessed through the pointer, regardless of whether the variable was initially defined as const or not.

Thus, the following is okay:

But the following is not:

Because a pointer to a const value is not const itself (it just points to a const value), the pointer can be redirected to point at other values:

Const pointers

We can also make a pointer itself constant. A const pointer is a pointer whose value can not be changed after initialization

To declare a const pointer, use the const keyword between the asterisk and the pointer name:

Just like a normal const variable, a const pointer must be initialized to a value upon declaration. This means a const pointer will always point to the same address. In the above case, ptr will always point to the address of value (until ptr goes out of scope and is destroyed).

However, because the value being pointed to is still non-const, it is possible to change the value being pointed to via dereferencing the const pointer:

Const pointer to a const value

Finally, it is possible to declare a const pointer to a const value by using the const keyword both before the type and before the variable name:

A const pointer to a const value can not be set to point to another address, nor can the value it is pointing to be changed through the pointer.

Recapping

To summarize, you only need to remember 4 rules, and they are pretty logical:

  • A non-const pointer can be redirected to point to other addresses.
  • A const pointer always points to the same address, and this address can not be changed.
  • A pointer to a non-const value can change the value it is pointing to. These can not point to a const value.
  • A pointer to a const value treats the value as const (even if it is not), and thus can not change the value it is pointing to.

Keeping the declaration syntax straight can be challenging. Just remember that the type of value the pointer points to is always on the far left:

Conclusion

Pointers to const values are primarily used in function parameters (for example, when passing an array to a function) to help ensure the function doesn’t inadvertently change the passed in argument. We will discuss this further in the section on functions.

6.11 -- Reference variables
Index
6.9a -- Dynamically allocating arrays

81 comments to 6.10 — Pointers and const

  • Sameer Verma

    Const pointer to a const value

    Finally, it is possible to declare a const pointer to a const value by using the const keyword both before the type and before the variable name:

    A const pointer to a const value can not be set to point to another address, nor can the value it is pointing to be changed through the pointer.

    • Alex

      It’s not necessary. A pointer to a const value can point to a non-const value -- that value is considered const when accessed through the pointer.

      It’s the same thing with references. A const reference can reference a non-const value.

  • hey Alex,
    pointers point to the address of a variable they are pointed to, so any change in the pointers will lead to a change in the original variable.

    now consider this program

    #include<iostream>
    using namespace std;
    int main()
    {
        int a=22;//a is assigned a value 22
        const int *ptr=&a;//ok, const ptr points to the address of a.
        cout<<*ptr*2<<endl;//gives 44
        cout<<a;// but why does the value of original variable does not change.
    }

    i know the question may be silly, but i didn’t seem to to understand the  function of pointer in this particular case

    • Alex

      Be careful when you say “any change in the pointers”, because you can change what address a pointer points to, and you can dereference the pointer to change the value it points to.

      In your example, you set ptr to point to variable a’s address. Then you access a’s value through *ptr, and multiply that value by 2, and print it. This doesn’t affect a’s value -- it’s just a result that’s calculated and thrown away.

      If you’d done this instead:

      That would actually change a’s value (through the pointer)

  • Lamont Peterson

    Alex,

    If I’m understanding the intent of this example snippet properly:

    Because a pointer to a const value is not const itself (it just points to a const value), the pointer can be redirected to point at other values:

    … then, shouldn’t both of those variable declarations (for value1 & value2) be "const int"?

    • Alex

      They can be, but it’s not necessary. A pointer to a const value can point at either a const value or a non-const value. In either case, the value will be treated as const when accessed through the pointer.

      • Lamont Peterson

        Alex,

        Good point.  Definitely worth noting.

        I think that while in the context of the lesson, the way it read for that example lead me to believe that the goal was for the pointer to be pointing to const int values (as in, it should be used only with type "const int" variables) but the pointer itself is NOT const (as in, the pointer can be changed to point somewhere else).  Thus, the ambiguity which led to my question.  Perhaps I was taking you too literally?

        Perhaps both points ought be mentioned in this lesson?

  • haihui li

    Hi,Alex
    For beginners, it is difficult to distinguish between variables that are pointer types or normal variables.

    • Alex

      Do you think so? Variables that are pointer types are declared with an asterisk, while normal variables are not…

      • haihui li

        thanks for your reply.If you add CONST, there will be chemical reactions between them。just like(int  *const ptr = …)The asterisk is far from ptr,but it is pointer type.Although I understand now,This problem bothering me for a long time。So,I think the way of thinking is more important than its grammar.Thanks again.

  • Finn St John

    Hi Alex,

    you say: A pointer to a const value is a (non-const) pointer that points to a constant value.

    You clearly say that the pointer SHOULD NOT BE constant but in you very first example after that, the pointer you initialize IS a constant.

    If this a mistake or am i missing something?

  • tf

    Hello,
    I was wondering how pointers interact with constexpr (variables getting evaluated at compile-time):

    VS17 output:

    I’m confused about ptr3 and ptr5. From my understanding ptr3 should not work, because the memory for value3 gets assigned at runtime and not at compile time, meaning that pointers can’t be constexpr, since the compiler can’t predict what memory address the OS will assign. Yet it only complains about being able to convert to a *const pointer (since it seems to be missing const). Isn’t const implied by constexpr?

    VS2017 seems to treat "constexpr const int *ptr" exactly the same to "const int const* ptr"?  

    When I run the same stuff in Clang 4.0 (clang++ prog.cc -Wall -Wextra -std=gnu++1z)

    It complains about "constexpr const int *ptr5 = &value5;" not being a constant expression, which makes sense to me since the compiler does not know what the memory address will be at compile time.

    Is this just a quirk in VS2017 or is it undefined behavior?

    • Alex

      I think this is a quirk of VS2017. Since the address of a variable isn’t known at compile time, I wouldn’t expect you to be able to set a constexpr pointer to a constexpr value. But this is pushing my knowledge of the subject, so it’s very possible I could be wrong.

  • justAnotherConfusedStudent

    So I’m confused. When you initialize a pointer (not a const pointer) and have it point to a const int, can the pointer be redirected to point at other, non-const values?

    • Alex

      You can’t make a non-const pointer point at a const int.

      • Rex Lucas

        Alex
        In the light of your fundamental statement at the top of this page:
        "A pointer to a const value is a (non-const) pointer that points to a constant value."

        I guess I am missing some subtle point in your reply to "justAnotherConfusedStudent". Are you able to elaborate, please?

        • Alex

          I think I misread his question.

          A non-const pointer to a const value can be redirected.
          A const pointer to a non-const value can not be redirected.

          Basically, the constness of the pointer determines whether the pointer can have the address it holds changed, just like the constness of a variable determines whether that variables value can be changed.

  • jenifer

    how can i deal with pointers to static int?

    • Alex

      A pointer to a static int works the same way as a pointer to a non-static int.

      • jenifer

        What about the life time of the pointer to static int? Is it same as the static int, if so i can use it to return by address in a function.

        • Alex

          The lifetime of a static int is until the end of the program, so yes, you could return a pointer to a local static variable and be fine.

          That said, I can’t think of a good use case for actually doing this -- if the caller needs access to the static int’s value, why wouldn’t you return by value instead?

  • Mehul

    Hi Alex

    O/P
    0x7ffff9bf6f80
    0x7ffff9bf6f80
    0
    25

    Queries
    Here pointer is pointing to a constant variable, And still modifying the values
    And strange thing is j remains 0 and *p is only updated to 25

    Can you please help me on understanding this

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter