Johann Gerell
Johann Gerell

Reputation: 25581

Can template metaprogramming be used to encrypt compile-time constant data?

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

Answers (2)

Janick Bernet
Janick Bernet

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

Kerrek SB
Kerrek SB

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 declaration

static 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

Related Questions