[cfe-dev] How to create a new builtin in clang?
Jonathan Sauer
jonathan.sauer at gmx.de
Fri May 18 12:32:53 PDT 2012
Hello Andy,
>> Maybe I'm missing something, but constexpr does exactly that
>
> It does and it doesn't. If you declare a variable 'constexpr' then you can expect that a compile-time-evaluated constant is assigned to it. However, a 'constexpr'-declared variable is forever immutable (which may not be what you want) and if you do not declare a variable 'constexpr' then you cannot assume it will be given an initial value which is compile-time-evaluated.
So far, so good. Although I don't see why the immutability should be a problem; after all, you
can simply say:
constexpr int firstValue = ...;
int i = firstValue;
...
constexpr int secondValue = ...;
i = secondValue;
> In this way, 'constexpr' can be considered merely a hint to the compiler, like 'inline' is: the compiler can choose whether to obey it or not, usually depending on the optimisation level.
I don't think that's correct. When using constexpr on a variable, this means that the variable's value
must be a compile-time constant, or the code does not compile:
static int foo()
{
return 42;
}
static void bar()
{
constexpr int i = foo();
}
This results in (clang TOT):
error: constexpr variable 'i' must be initialized by a constant expression
constexpr int i = foo();
^ ~~~~~
Changing this to:
static constexpr int foo() // <=== now is constexpr
{
return 42;
}
static void bar()
{
constexpr int i = foo();
}
This compiles perfectly with clang TOTO.
Otherwise it would not be possible to use a constexpr variable as a non-type template parameter:
template <int>
struct Baz {};
static void bar()
{
constexpr int i = 42;
Baz<i> baz;
}
This compiles, but only because <i> is a constant expression, and constant expressions must be known
at compile-time.
> Using __builtin_constant_p(...), it is possible to test whether an expression can be compile-time evaluated, the next logical step would be a builtin which returns the result of the evaluation itself. It would form a contract between user and compiler: the user would be sure that as long as his code compiles, his expression is evaluated by the compiler and never at runtime.
That's what using constexpr on a variable does :-)
(<www2.research.att.com/~bs/sac10-constexpr.pdf> explains about the rationale behind constexpr)
HTH,
Jonathan
More information about the cfe-dev
mailing list