Может ли метапрограммирование шаблона использоваться для шифрования постоянных данных времени компиляции?
Позвольте мне объяснить, что я имею в виду на примере. Допустим, я записываю информацию о недостающей строке кода, например:
if (index > MaxIndex) { Log(__FILE__); abort(); }
Можно ли каким-то образом (с метапрограммированием шаблона или другой магией) написать Log()
так что постоянная строка времени компиляции, которая заменяет __FILE__
становится зашифрованным, так что фактические данные, которые используются в двоичном файле, являются зашифрованной строкой во время компиляции? Если нет, то почему?
Ваше предположение неверно. C99 только определяет __func__
, но GCC предлагает __FUNCTION__
а также __PRETTY_FUNCTION__
как расширения, которые ведут себя одинаково. Ни один из них не макрос, скорее идентификаторы. Например. С11, 6.4.2.2:
Идентификатор
__func__
должен быть неявно объявлен переводчиком, как если бы,
сразу после открывающей скобки каждого определения функции, объявлениеstatic const char __func__[] = "function-name";
появился, где имя-функции имя лексически заключающей в себя функции
К сожалению, в C ++ 11 static const char []
не является константным выражением, и поэтому ни один из вышеуказанных идентификаторов не может быть использован в качестве аргумента шаблона-метапрограммы.
(В отличие от __FILE__
а также __LINE__
являются макросы, которые заменяются литералами, так что вы можете легко обработать их статически.)
(Простой пример витрины 🙂
template <unsigned int I, unsigned int N>
constexpr char get(char const (&arr)[N]) { return arr[I]; }
template <char C> struct Foo { };
int main()
{
Foo<get<2>(__FILE__)> ok;
Foo<get<2>(__FUNCTION__)> err1; // "error: the value of ‘__func__’ is not usable in a constant expression"Foo<get<2>(__PRETTY_FUNCTION__)> err2;
Foo<get<2>(__func__)> err3;
}
С C ++ 11 это должно быть возможно с простым constexpr
функции, которые могут быть оценены во время компиляции. Это должно быть намного более читабельным, чем мета-программирование некоторых шаблонов (однако, оно может молча вернуться к оценке функции во время выполнения — что может или не может быть желательно в вашем случае). Также примите во внимание то, о чем писал @KerrerSB __func__
не быть постоянным выражением.