Reputation: 25581
Can template metaprogramming be used to encrypt compile-time constant data?
Let me explain what I mean with an example. Let's say I log information about a failing code line, like this:
if (index > MaxIndex) { Log(__FILE__); abort(); }
Could it somehow be possible (with template metaprogramming or other magic) to write Log()
so that the compile-time constant string that replaces __FILE__
gets encrypted so that the actual data that is used in the binary is the compile-time encrypted string? If not, why?
Upvotes: 1
Views: 706
Reputation: 21194
With C++11 it should be possible with simple constexpr
functions which can be evaluated at compile time. That should be much more readable than some template meta-programming (however, it might silently fall back to runtime evaluation of a function - which might or might not be desirable in your case). Also take into account what @KerrerSB wrote about __func__
not being a constant expression.
Upvotes: 1
Reputation: 477100
Your assumption is incorrect. C99 only defines __func__
, but GCC offers __FUNCTION__
and __PRETTY_FUNCTION__
as extensions, which behave the same. None of them are macros, but rather identifiers. E.g. C11, 6.4.2.2:
The identifier
__func__
shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declarationstatic const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function
Unfortunately, in C++11, static const char []
is not a constant expression, and thus none of the above identifiers can be used as template-metaprogram arguments.
(By contrast, __FILE__
and __LINE__
are macros that are replaced with literals, so you could very well process those statically.)
(Simple showcase example:)
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;
}
Upvotes: 3