1

I tried to run a program based on constexpr.

Code:-

#include <iostream>
using namespace std;

int main()
{

        const int i = 10;
        constexpr int j = 10;

        constexpr int val1 = i;
        constexpr int val2 = j; 

        return 0;
}

In the book I follow, it is mentioned that if you assign a const to a constexpr variable, it is an error.

But my program compiles without any complaints.

Am I missing something?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Sathish
  • 227
  • 3
  • 11
  • The expression `constexpr int val1 = i;` assigns value of `i` to `val1` – user3337714 Jul 12 '15 at 09:23
  • 1
    You're not assigning to the `constexpr` variables, you're initializing them. You could write the same as `constexpr int val1{ i };` — with that notation, you see immediately that no assignment is involved. – celtschk Jul 12 '15 at 10:19

1 Answers1

8

Ammendment

celtschk made a good point in the comments below the question. That is, you are not assigning to anything in your code. You are only initializing. Assigning from a const to a constexpr is indeed an error. So if that's what your book said, then it was not incorrect. However, this would be a strange point to make, since assigning in the other direction (from a constexpr to a const) is also an error. Anyway, the rest of the answer is under the assumption that when you said "assign", you meant "initialize".

End of Ammendment


Your book is incorrect (assuming you are not incorrectly paraphrasing what it said). A const integral which is initialized with a constant expression, is itself a constant expression. So i is a constant expression, and can be used to further initialize other constant expressions.

quoth the standard, 5.19/2

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
...
— an lvalue-to-rvalue conversion (4.1) unless it is applied to:
...
— a non-volatile glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
...

However, note that a const which is not initialized with a constant expression, is of course not a constant expression:

int a = 10;
const int b = a;
constexpr int c = b; // error

Also note that this only applies to integer and enum types. Not, for example floats and doubles.

const float a = 3.14;
constexpr float b = a; // error

Although some compilers might allow that (I believe MSVC does)

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274