3

In C++ Primer 5th, it says that

constexpr imposes a top-level const on the objects it defines.

So how I can I declare a pointer with a constexpr specifier imposing a low-level const, i.e. a pointer pointing to a constexpr object?

4
  • 1
    At least as far as I remember that statement just means that constexpr also implies const upon the variable. So it would need a const pointer? What have you tried so far? Why would you need a pointer to it in the first place? Or do you just want to know how? Commented Jun 13, 2016 at 11:54
  • Either the entire expression is constexpr or it's not. Doesn't really make much sense to have something that's partially constexpr. const and constexpr are also orthogonal concepts. constexpr implies const but not the other way around. Commented Jun 13, 2016 at 11:57
  • @sleeptightpupper ...until c++14 whereafter it is perfectly legal to have mutable constexpr objects Commented Jun 13, 2016 at 12:02
  • @RichardHodges constexpr is to mutable as const is to volatile. Doesn't contradict what I said. Commented Jun 13, 2016 at 12:03

1 Answer 1

2

A constexpr object is an object just like any other. The fact that its value is computed at compile time does not alter this.

Often, the compiler will seek to avoid actually emitting code to create const values and objects if it knows that they will never be needed , for example when objects are static const.

By taking the address of an object, whether constexpr, static const or an auto variable, the compiler is forced to actually create the object.

So:

constexpr int i = 5;    // need not be actually created

const int* pi = &i;     // but now it must be, because we took its address

constexpr const int* pi2 = &i;  // constexpr pointer to const object - we took its address so it must exist


const void emit(int);

int main()
{
  emit(i);
  emit(*pi);
  emit(*pi2);
}

results in:

main:
        subq    $8, %rsp
        movl    $5, %edi         <-- compiler knows it's a fixed value
        call    emit(int)

        movq    pi(%rip), %rax   <-- compiler dereferences the pointer
        movl    (%rax), %edi
        call    emit(int)

        movl    $5, %edi      <-- compiler knows it's a fixed value
        call    emit(int)

        xorl    %eax, %eax
        addq    $8, %rsp
        ret
pi:
        .quad   i
i:
        .long   5
Sign up to request clarification or add additional context in comments.

3 Comments

Well, straightforward description. But I still can't figure out why there is no such way to define a low-level constexpr pointer?
constexpr is not part of the type signature. It's more like an instruction to the code generator (it's more than that, of course). So the idea of pointing at a constexpr object makes no sense, because there is no such thing as an object of type constexpr int (for example). The type of that would be const int - it would just happen to be computed at compile time (so you could use it in static asserts and template arguments, for example)
Excellent explanation. Thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.