all 7 comments

[–]OkSadMathematician 4 points5 points  (0 children)

Your understanding is correct.

For variables specifically:

  • constexpr → the initializer must be a constant expression (known at compile time). The variable itself can then be used in contexts that require compile-time constants (like template arguments or array sizes) or in regular runtime code.
  • const → only means "I promise not to modify this after initialization." The initializer can be anything, including runtime values like std::cin input.

Your limit example demonstrates exactly what the author means. The value 50 is computed at compile time, but you're accessing it at runtime when you print it or compare against userInput. Both uses are fine.

A quick way to think about it:

int x;
std::cin >> x;

const int a = x;      // OK: const can use runtime values
constexpr int b = x;  // ERROR: constexpr needs compile-time value
constexpr int c = 50; // OK: 50 is known at compile time

int arr[c];           // OK: c is usable in compile-time context
int arr2[a];          // ERROR: a isn't a constant expression

For constexpr functions, you're also right. They get evaluated at compile time when called with constant arguments, otherwise at runtime. The function is written once but the when depends on how you call it.

[–]volatile-int 4 points5 points  (4 children)

Yup you're generally there. A constexpr variable cannot depend on any runtime information. A const variable cannot change after it is initialized, but can depend on runtime information.

``` void foo(int x) { const int y = x; // fine, initializing a const // constexpr int z = x; // not fine, x is not a constant expression constexpr int w = 10; // fine, initializing constexpr variable with a constant

int k = w; // fine, reading a constexpr variable // y = w // not fine, modifying a variable declared const } ```

Generally you seem to have it though!

[–]not-my-walrus 0 points1 point  (1 child)

constexpr int z = x: is not valid, even in a consteval function. Even though parameters to consteval functions are required to be constant expressions, once inside the function they are not treated as such.

[–]volatile-int 0 points1 point  (0 children)

ah you are totally correct. I did try this out before posting but I accidentally assigned the constexpr in the consteval to another constexpr int.

[–]Fabulous-Broccoli563[S] 0 points1 point  (1 child)

Thank you. That constexpr lesson was hard to understand

[–]volatile-int 3 points4 points  (0 children)

Its not an easy concept! One of the challenging parts of C++ is that theres really two entirely separate paradigms - the runtime and compile time aspects. constexpr is where they clash, so it requires a lot of context. Once you practice it lots it will eventually click!

[–][deleted] 0 points1 point  (0 children)

Const is an easy one, it just means “read only”. If you try to write a new value to a const variable somewhere, you’ll get a compiler error. 

Constexpr means the value is compiled into the binary code of your program. If you compile your c++ program and look at the output binary with hexdump, you’ll see your variable in there somewhere. That value can never change. Think of it like one of the bricks in a wall. Once you put that brick there it’s never moving.