[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