[cfe-dev] C++11: new builtin to allow constexpr to be applied to performance-critical functions

Jordan Rose jordan_rose at apple.com
Sat Oct 20 12:24:40 PDT 2012


On Oct 19, 2012, at 23:27 , Andy Gibbs <andyg1001 at hotmail.co.uk> wrote:

> On Saturday, October 20, 2012 7:50 AM, Chandler Carruth wrote:
>> [...snip...] Let me hypothesize a different interface:
>> 
>> This stays the same...
>> constexpr int constexpr_strncmp(const char *p, const char *q, size_t n) {
>> return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : constexpr_strncmp(p+1, q+1, n-1);
>> }
>> 
>> 
>> But here we do something different on the actual declaration:
>> [[constexpr_alias(constexpr_strncmp)]]
>> int strncmp(const char *p, const char *q, size_t n);
>> 
>> When parsing the *declaration* of this function, we lookup the function
>> name passed to constexpr_alias. We must find a constexpr function with an
>> identical signature. Then, at function invocation substitution of strncmp,
>> we instead substitute the body of constexpr_strncmp.
>> 
>> This seems more direct (no redirection in the code), and it also provides
>> a specific advantage of allowing this to be easily added to an existing
>> declaration in a declaration-only header file without impacting or
>> changing the name of the runtime executed body or definition.
> 
> I'd be very happy with this solution.  I come across precisely the problem
> raised by Richard on a very regular basis and have different workarounds
> for both gcc and clang.  I'd love to see something "standard" emerging!
> 
> For my side, I'd still like some way of declaring a function to be used
> only in a constexpr environment, meaning that the compiler gives an error
> up front when a function is then used in a non-constexpr environment.  The
> above proposal will provide a link-time error if the non-constexpr function
> is not defined, which is half-way there.  Perhaps using the "unavailable"
> attribute in conjunction with "constexpr_alias" would be the compile-time
> solution...

While throwing things out there, why not just optionally allow constexpr functions to coexist with non-constexpr functions of the same name, like inline and non-inline? That would solve both the original problem and Andy's problem.

  // Primary declaration.
  int strcmp(const char *p, const char *q, size_t n);

  // This declaration will be used in any constexpr contexts.
  // Non-constexpr contexts will use the declaration above (which may be inline)
  constexpr int strcmp(const char *p, const char *q, size_t n) {
    return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : strcmp(p+1, q+1, n-1);
  }

This avoids both new builtins and having to come up with a manually-mangled name for the alternate implementation. But it is most definitely a language change.

And for Andy's problem, you'd then get...something like this?

  constexpr int foo(int n) {
    return n + 1;
  }

  int foo(int n) = delete;

...but I have not thought about the problems in implementing this.
Jordan



More information about the cfe-dev mailing list