I'm having difficulties grasping what does it mean to be non-evaluated expression?
For example, if the compiler does compile time check if an expression evaluates to true then how is that expression NOT evaluated?
Everything that may be changed at runtime cannot be evaluated at compile time
Thus if sizeof(/* runtime expression */) should result in compile time error because sizeof doesn't evaluate expressions, but we know this is not the case.
Is it valid to say that sizeof(/* runtime expression */) results in sizeof of the result of an expression that is evaluated at runtime but not evaluated by the sizeof operator itself?
#include <iostream>
int i = 99 ;
// *** warning: expression with side effects has no effect in an unevaluated context
void foo() noexcept( noexcept( sizeof(++i) == 0 ) ) { std::cout << "foo is called\n" ; }
int main()
{
// *** warning: expression with side effects has no effect in an unevaluated context
std::cout << std::boolalpha << ( sizeof(++i) > 0 ) << ' ' << noexcept( foo() ) << '\n' ;
std::cout << i << '\n' ; // 99 (++i is in unevalated expressions)
}
#include <iostream>
short a = 0;
long b = 1;
int main()
{
std::cout << sizeof(a + b) << std::endl;
}
returns sizeof(long) but does not add a + b,
a + b could be either compile time or run time expression, so I guess sizeof only takes static type of variables somehow and determines resulting type.
What I still don't understand is at which point it does so?
is it compile time or run time?
So of course the compiler looks at the expression to see that it doesn't have any syntax errors and to determine the type, etc. I guess this is a form of "evaluation" using the normal English meaning of the word but in programming "evaluate" has a special meaning so in order to avoid confusion it's best to use different words to describe this.
Just to be clear, I didn't mean we should avoid the word "evaluate" when talking about finding out the value (and possibly getting the side-effects) of an expression. This is well-established vocabulary in our field. What we should not do is use "evaluate" to mean other things, at least not when talking about things related to expressions, because that would only lead to confusion.
static_assert is a good trick to see if it's evaluated at compile time.
It's a good trick to see if an expression can be evaluated at compile time, but it doesn't necessarily mean the same expression will be evaluated at compile time when used in another context.