пользовательские литералы c ++ 11, конфликтующие с дихотомией компиляции / выполнения

Я знаю, что стандарт ISO C имеет большое значение для разделения поведения перевода и поведения выполнения, частично для того, чтобы кросс-компиляторы не несли среду выполнения каждой цели.

Под этим я подразумеваю, что компилятор имеет ограниченную доступную информацию по сравнению с запущенной программой. Это ограничивает то, что вы можете сделать в исходном коде, например, не инициализировать переменную на основе возвращаемого значения из функции, подобной этой:

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

Что меня интересует, так это то, как пользовательские литералы в C ++ 11 вписываются в эту схему. Так как буквальная оценка опирается на функцию, что мешает этой функции делать такие вещи:

  • возвращение случайного значения (даже если оно основано на вводе, таком как 42_roughly давая вам значение между 40 и 44)?
  • есть побочные эффекты, такие как изменение глобальных переменных?

Означает ли тот факт, что функция должна быть вызвана, не неужели литералы в том смысле, что их вычисляют во время компиляции?

Если это так, в чем преимущество этих литералов перед любым другим вызовом функции. Другими словами, почему это:

int xyzzy = 1101_1110_b;

предпочтительнее:

int xyzzy = makeBin ("1101_1110");

?

1

Решение

Секрет в том, объявляете ли вы пользовательские литеральные функции как constexpr или нет.

Сравните это (обычная функция времени выполнения):

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

С этим (константа времени компиляции, static_assert работает):

#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;
}

Очевидно, что объявление функции constexpr ограничивает все утверждения в пределах constexpr также, или константы времени компиляции; не допускается случайное число махинаций.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]