There's a problem with making a new thread. Sometimes it won't be shown and I think it's not created. Then I need to redo that. Not my problem, but the website's.
Anyway, back to the question:
The function "square" needs a double, we supply that by double var = 17;. Then, the function must give us a constexpr result to be used for the expression max2.
Everything looks harmless and fine. So why should the compiler give an error!? :(
Another problem with the forum is that I can't apply formats for the question! I ought to create it as plain text then step to modify that by using some formats to be read and understood easily! :( :(
I hope someone remedies that problem.
Then, the function must give us a constexpr result to be used for the expression max2.
You are misunderstanding constexpr: when applied to a function, it means "this function may be used in a constant expression". Note the word "may": constexpr is not a guarantee.
In particular, if you call a constexpr function with arguments (like var) that are not also constant expressions, the result will be computed at run-time. Expressions that must be evaluated at run-time are not constant expressions.
if you call a constexpr function with arguments (like var) that are not also constant expressions, the result will be computed at run-time.
It doesn't necessarily mean that it will be computed at runtime. The compiler is free to optimize the code as it like as long as the observable behaviour is the same. What we do know is that the result of square(var) is not a constant expression, because var is not a constant expression, so it cannot be used to initialize a constexpr variable.
Yes, thank you.
When I make the var a constexprdouble, the code works well.
But despite consts and changable variables why do we need constexprs? That is, where are they useful please?
constexpr is useful as a marker to clarify that a function is (always going to be) pure -- both for the compiler and for the programmer.
It is useful wherever computations are required at compile-time (for example, to compute array dimensions).
Beyond that, constexpr has the potential to simplify many especially complex meta-programs. This is to say that it has already been a substantial boon to language experts - i.e., the folks who write your libraries - and it seems like there will continue to be substantial improvements.
I tried to say that constexpr can be used to signal that a function is always logically pure. I didn't want to imply that it was guaranteed.
When I write a function whose result depends solely on its arguments, I have been marking it constexpr, (hopefully) barring issues that would make my program ill-formed. That is, I have been making things constexpr even when I do not currently intend for them to be used in a constant expression.
While I understand that the definition of foo() is well-formed, my intuition tells me that applying constexpr to it is a logical error, because its contract should not change depending on the location of the call.
Notice that if I call foo() outside of a constant expression, I can pass any integer, but if I call it (e.g.) in a constant initializer, it is only legal to pass nonnegative values. This is awful, and I would argue that foo() should never have been marked constexpr in the first place.
I've been using constexpr to denote "pure function". Is this a mistake? Should I be more conservative?
I've been using constexpr to denote "pure function". Is this a mistake? Should I be more conservative?
That might have been the initial intention, but at the moment I think "pure" is a stronger promise than what consexpr functions are supposed to be.
In C++11 constexpr implied const for member functions. This was later changed. Constexpr member functions are now allowed to modify data members of the object that the function is called on which is necessary in order to be able to call non-const member functions on objects inside constexpr functions.
In C++20 std::swap will be marked constexpr. It's obviously not a pure function, because it modifies its arguments, but it is still a useful function to be able to use in constexpr functions.
constexpr functions are pure: they can have no side effects.
Which is clearly wrong. I've made a note and will open an issue either tomorrow (Saturday the 29th) or Sunday. If it doesn't exist already, perhaps I'll suggest a guideline against functions like foo().
Anyway, I digress. I agree with you, @Peter - since the constexpr evaluator is stateful, it cannot imply "pure", even at compile-time. (Maybe it did in 2011 - sorry, @frek.) But, perhaps the claim is backwards: If "pure" is stronger than constexpr, should I mark pure functions constexpr when reasonable?
Since there are lots of extra concerns about whether or not it's okay to mark something constexpr, I imagine the answer is "maybe". If this is the case, at best, constexpr can be considered a hint - "this function is maybe pure".
In the finished, compiled code, const does not exist. constexpr does not exist. They are just messages to the compiler.
const says to the compiler "while you're making the output executable or library, if you see anything that tries to change this value (after the value has been initialised), that's an error and you are to stop compiling and tell me".
constexpr says to the compiler "this is const, but also, this is something that can be evaluated at compile time - if that's helpful to you, great, if not, also fine".
It is possible to have a const value that can NOT be evaluated at compile time; every constexpr variable is const, but not every const variable is constexpr
The above is... a bit rough, and applies to variables rather than functions (since that's what we're talking about).