0

I'am learning C++ so I'am currently reading the book "C++ Primer".

I was reading some examples about the "constexpr variables" and I just want to try a basic code that I just wrote but it doesn't compile I don't know why.

This is the code :

#include <iostream> using namespace std; int j = 8; const int *p = &j; int main() { constexpr int i = *p; // *p should be 8. return 0; } 

The compiler says : "the value of 'p' is not usable in a constant expression"

If I replace the "constexpr" by "const" no problem at all but I think that because the value of *p should be known at compile time there shouldn't be any problems.

I don't know where I made a mistake. (Please be tolerant my first language is French)

3
  • 2
    What are you trying to achieve? j and p are not constexpr, so how can i be constexpr? Commented Aug 2, 2020 at 12:42
  • 1
    What if there were some code that ran before main (e.g. a global constructor) that modified the value of j? Commented Aug 2, 2020 at 12:43
  • Change the other lines to constexpr int j = 8; and constexpr const int *p = &j; and it should work. Commented Aug 2, 2020 at 12:46

2 Answers 2

2

The reason this does not compile is because J is not const or constexpr.

Also note P is "just" const pointer.
This means *P can not be changed, but P itself is free to be changed.
Here is an example:

int f(){ int a = 5; int b = 6; int *p = nullptr; p = &a; // *p -> a -> 5 p = &b; // *p -> a -> 6 return *p; } 

I want to clarify something for const vs constexpr:

const is not constexpr, but some for some primitive types there is no difference:

This compiles:

const int j = 8; constexpr const int *p = &j; int main(){ constexpr int i = *p; return i; } 

Also this compiles:

constexpr int j = 8; constexpr const int *p = &j; int main(){ constexpr int i = *p; return i; } 

However this does not compiles:

const int j = 8; const int *const p = &j; int main(){ constexpr int i = *p; return i; } 
Sign up to request clarification or add additional context in comments.

11 Comments

Ok but now, if j is a const int variable and if my pointer is constant (const int *const p = &j;) ? Now, the value of j can't change and my pointer will always point to j so what's wrong ?
@Louigi115 like I said p is not consexpr. niether is j. Read this
@Louigi115 • constconstexpr
@JHBonarius Great, thank you. Indeed it works when I use constexpr. But I still don't really understand everythings. Without using a pointer I have no problem if j is const int. But why my pointer has to be declare like constexpr const int *p and not just like const int *const p. Like your link say, I need to have constant expression but const int j =10; is a constant expression, I don't understand why I should have constexpr everywhere.
@Louigi115 As cigien points out in his answer const int i = 10; is a special case. In that example i is a constexpr.
|
1

It seems the fundamental misunderstanding you have is the difference between an object being const vs constexpr. A variable being const means that it's logically const, i.e. the value cannot be changed once it's initialized. That does not mean that the value is known at compile time, which is what constexpr signifies.

For some type T

T t = {}; // not const, not constexpr const T t = {}; // const, but not constexpr constexpr T t = {}; // constexpr, also implies const 

All good so far, but there's an additional wrinkle: a variable of integral or enumeration type that is const and is assigned a constant expression, is also constexpr. There are good reasons for this difference, but what that means is:

const int i = 42; // i is int, and const, so it's also constexpr !! 

And of course, if you want to use an expression as a constant expression, it must have been declared as a constexpr variable or function.

1 Comment

Oh ok, I see. This is why it works with just another variable declare as const but my pointer needs to be explicitly declared as constexpr. Thank you

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.