I wonder, because predefined literals like ULL
, f
, etc. are obviously resolved at compile time. The standard (2.14.8 [lex.ext]) doesn't seem to define this, but it seems to tend towards runtime:
[2.14.8 / 2]
A user-defined-literal is treated as a call to a literal operator or literal operator template (13.5.8). To determine the form of this call for a given user-defined-literal L with ud-suffix X, the literal-operator-id whose literal suffix identifier is X is looked up in the context of L using the rules for unqualified name lookup (3.4.1). Let S be the set of declarations found by this lookup. S shall not be empty.
(emphasis mine.)
However, to me this seems to introduce unnecessary runtime-overhead, as literals can only be appended to values that are available at compile-time anyways like 13.37f
or "hello"_x
(where _x
is a user-defined-literal).
Then, we got the templated user-defined-literal, that never really gets defined in the standard AFAICS (i.e., no example is given, please prove me wrong). Is that function somehow magically invoked at compile time or is it still runtime?
Yes, you get a function call. But function calls can be compile time constant expressions because of constexpr
literal operator functions.
For an example, see this one. As another example to show the advanced form of constexpr
computations allowed by the FDIS, to have compile time base-26 literals you can do
typedef unsigned long long ull;
constexpr ull base26(char const *s, ull ps) {
return (*s && !(*s >= 'a' && *s <= 'z')) ? throw "bad char!" :
(!*s ? ps : base26(s + 1, (ps * 26ULL) + (*s - 'a')));
}
constexpr ull operator "" _26(char const *s, std::size_t len) {
return base26(s, 0);
}
Saying "bcd-"_26
will evaluate a throw-expression, and thereby cause the return value to become non-constant. In turn, it causes any use of "bcd-"_26
as a constant expression to become ill-formed, and any non-constant use to throw at runtime. The allowed form "bcd"_26
evaluates to a constant expression of the respective computed value.
Note that reading from string literals is not explicitly allowed by the FDIS, however it presents no problem and GCC supports this (the character lvalue reference is a constant expression and the character's value is known at compile time). IMO if one squints, one can read the FDIS as if this is allowed to do.
Then, we got the templated user-defined-literal, that never really gets defined in the standard AFAICS (i.e., no example is given, please prove me wrong)
The treatment of literals as invoking literal operator templates is defined in 2.14.8. You find more examples at 13.5.8 that detail on the literal operator function/function templates itself.
Is that function somehow magically invoked at compile time or is it still runtime?
The keyword is function invocation substitution. See 7.1.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With