c++ - Using argc in a constexpr, is it strictly required that any sub-expression involved be a constant expression? -
example:
int main(int argc, char**) { constexpr int = argc * 0; (void)a; constexpr int b = argc - argc; (void)b; return 0; }
argc
not constant expression, compiler still able compute results of a
, b
in compile time (i.e. 0
) in both cases.
g++ accepts code above, while clang , msvc14 reject it.
does standard allows compiler being smart g++ regard constexpr
?
neither argc * 0
nor argc - argc
constant expressions, lvalue-to-rvalue conversion allowed in cases none of them apply here. if @ draft c++11 standard section 5.19
[expr.const] lays out exceptions. says:
a conditional-expression core constant expression unless involves 1 of following potentially evaluated subexpression [...]
and has several bullets including following on lvalue-to-rvalue conversion:
an lvalue-to-rvalue conversion (4.1) unless applied to
a glvalue of integral or enumeration type refers non-volatile const object preceding initialization, initialized constant expression, or
a glvalue of literal type refers non-volatile object defined constexpr, or refers sub-object of such object, or
a glvalue of literal type refers non-volatile temporary object lifetime has not ended, initialized constant expression;
it interesting note gcc not accept following code (see live):
constexpr int = argc * 2;
so looks gcc saying know result 0 , therefore performs constant folding , not need perform lvalue-to-rvalue conversion of argc
determine result.
unfortunately don't see provisions in section 5.19
allows kind of short-circuiting. looks similar case in int a=1, || 1 constant expression? has bug report no 1 gcc team has replied one. added comment bug report indicating seems related.
mark's comment below indicates bug:
there whole c++-delayed-folding branch on gcc developers working, delay number of optimizations , might fix this. important other reasons, rejecting code in question low priority
do constant expressions strictly require every sub-expression constant expression? no, example 5.19
says: (emphasis mine)
a conditional-expression core constant expression unless involves 1 of following potentially evaluated subexpression (3.2), but subexpressions of logical , (5.14), logical or (5.15), , conditional (5.16) operations not evaluated not considered [...]
so following constant expression:
constexpr int = false && argc * 0;
because argc * 0
not evaluated since &&
evaluates left-to-right , short-circuits.
Comments
Post a Comment