Question

I know the ISO C standard make a big deal about separating translation behaviour and execution behaviour, partly to ensure cross-compilers don't have to carry the execution environment of every target.

By that, I mean the compiler has limited information available to it compared to a running program. That limits what you can do in the source code, such as not initialising a variable based on the return value from a function like this:

int twice (int val) { return val * 2; }
int xyzzy = twice (7);
int main () { printf ("%d\n", xyzzy); return 0; }

What I'm curious about is how user defined literals in C++11 fit into this scheme. Since the literal evaluation relies on a function, what's to stop that function doing things like:

  • returning a random value (even if based on the input such as 42_roughly giving you a value between 40 and 44)?
  • having side effects, such as changing global variables?

Does the fact that a function have to be called means that these aren't really literals in the sense of being calculated at compile time?

If that's the case, what's the advantage of these literals over any other function call. In other words why is:

int xyzzy = 1101_1110_b;

preferable to:

int xyzzy = makeBin ("1101_1110");

?

Était-ce utile?

La solution

The secret is all in whether you declare the user-defined literal functions as constexpr or not.

Compare this (normal execution-time function):

#include <iostream>
int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () { std::cout << xyzzy << "\n"; return 0; }

With this (compile-time constant, the static_assert works):

#include <iostream>
constexpr int operator "" _twice(unsigned long long num) { return num*2; }
int xyzzy = 7_twice;
int main () {
    static_assert(7_twice == 14, "not compile time constant");
    std::cout << xyzzy << "\n";
    return 0;
}

Obviously, declaring a function constexpr restricts all statements within to be constexpr also, or compile-time constants; no random number shenanigans allowed.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top