Hi clang experts,
I submitted a constexpr-related paper to the C++ standards committee about
6 months ago. To summarize the paper, I want to find a way to:
a. Allow constexpr code to have two implementations: one for constant
evaluation, and one for runtime evaluation.
b. I also wish for a way for a programmer to insist that a particular
constexpr function may only be used for constant evaluation. If the
constexpr function were to generate runtime code I want to be able
to generate a compile- or link-time error.
The full version of the paper can be found here:
Reception from the committee was somewhat chilly. But they said that if I
were to pursue the project, I should try Approach C: a trait.
Richard Smith kindly offered some additional advice about such a trait.
Here’s my interpretation of Richard’s suggestion:
o Create a nullary trait named
constexpr bool std::is_constant_evaluation().
It is not a template and it accepts no arguments.
o The return value of this trait depends on the context in which it
is called. If it is called in a situation that requires compile-time
evaluation of a value, then it returns true. One such situation
occurs when a variable that is declared constexpr is evaluated. Another
such situation is when an Integer Constant Expression (ICE) is required.
Yet another such situation is when a static_assert is evaluated. There
may be other similar situations as well.
o Under all other situations, the trait returns false.
Such a trait could be used with a conditional in a constexpr function to
select between a compile-time or a run-time implementation.
I’m attempting to implement such a trait in clang. I want an implementation
for two reasons:
a. I want to make sure that the trait will meet my requirements.
b. If I submit a follow-on paper to the C++ standard committee, I would
like that paper to be based on experience with an implementation.
I am not a compiler person, but I’m game to try hacking clang. I’ve
made an initial attempt at an implementation. I feel like my initial
attempt, adding a new unary trait to clang (and always passing void), is not
going well. I’ve created a new unary trait that always returns false with
surprisingly little damage to the clang code base. But I haven’t yet figured
out how to examine the context so I know when to return true. It also
appears that clang caches the trait result. So, even if I solved the context
problem, once the trait is evaluated it would always return the same value,
regardless of each new context.
So I’m asking for guidance.
Suggestions? Thanks in advance.