I believe the simple test that makes the code above not compile does not evaluate potential results of conditional expressions: only one branch needs to be a constant expression, and the test does not reason about "value == value" always taking one branch. So the version with the tautological test will compile by itself, but you'll never be able to use it in a constexpr context, versus the simple function above is recognized as not being constexpr.
Making built-in functions with simple arithmetic meanings constexpr is a different issue.
I believe the simple test that makes the code above not compile does not
evaluate potential results of conditional expressions: only one branch
needs to be a constant expression, and the test does not reason about
"value == value" always taking one branch. So the version with the
tautological test will compile by itself, but you'll never be able to use
it in a constexpr context, versus the simple function above is recognized
as not being constexpr.
Making built-in functions with simple arithmetic meanings constexpr is a
different issue.
Thanks for the reply. Two questions:
1. know of a way to use builtin functions (like clz) in a constexpr context?
I am figuring I need to re-implement it, no way to use the CPU instruction
at compile time (?)
2. why does a branch allow it to be compiled? I would have thought that the
compiler would inspect both branches and insist they both be a const
friendly.
So, I should expect the branched version compile to fail if I actually use
it in a constexpr context? Should have tried that..
Sebastian Redl wrote
> I believe the simple test that makes the code above not compile does not
> evaluate potential results of conditional expressions: only one branch
> needs to be a constant expression, and the test does not reason about
> "value == value" always taking one branch. So the version with the
> tautological test will compile by itself, but you'll never be able to use
> it in a constexpr context, versus the simple function above is recognized
> as not being constexpr.
>
> Making built-in functions with simple arithmetic meanings constexpr is a
> different issue.
Thanks for the reply. Two questions:
1. know of a way to use builtin functions (like clz) in a constexpr
context?
I am figuring I need to re-implement it, no way to use the CPU instruction
at compile time (?)
__builtin_clz works in constant expressions in recent Clang revisions. You
only need to upgrade =)
2. why does a branch allow it to be compiled? I would have thought that the
compiler would inspect both branches and insist they both be a const
friendly.
The compiler does inspect both branches, but it only insists that *one* of
them is constexpr-friendly. It's valid for a ?: to select between a
potentially-constant expression and a never-constant expression within a
constexpr function.
So, I should expect the branched version compile to fail if I actually use
1. know of a way to use builtin functions (like clz) in a constexpr
context?
I am figuring I need to re-implement it, no way to use the CPU
instruction
at compile time (?)
__builtin_clz works in constant expressions in recent Clang revisions. You
only need to upgrade =)
Right.. good to know. Did this change come in 3.3 or very latest SVN?
Richard Smith wrote
2. why does a branch allow it to be compiled? I would have thought that
the
compiler would inspect both branches and insist they both be a const
friendly.
The compiler does inspect both branches, but it only insists that *one* of
them is constexpr-friendly. It's valid for a ?: to select between a
potentially-constant expression and a never-constant expression within a
constexpr function.
Gotcha. I expected it to be a bit more draconian on guaranteeing constexpr
in all branches. Thx for the follow up.
know of a way to use builtin functions (like clz) in a constexpr
context?
I am figuring I need to re-implement it, no way to use the CPU
instruction
at compile time (?)
__builtin_clz works in constant expressions in recent Clang revisions. You
only need to upgrade =)
Right… good to know. Did this change come in 3.3 or very latest SVN?
Sorry, I don’t remember. Maybe someone with 3.3 can test this for you. I think it was more recently than that, though.