On Oct 19, 2012, at 23:27 , Andy Gibbs <andyg1...@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