模板元编程可以用来加密编译时常量数据吗?
让我用一个例子来解释我的意思。假设我记录了有关失败代码行的信息,如下所示:
if (index > MaxIndex) { Log(__FILE__); abort(); }
是否有可能(使用模板元编程或其他魔法)编写Log()
以便替换的编译时常量字符串__FILE__
被加密,以便二进制中使用的实际数据是编译时加密字符串?如果不是,为什么?
模板元编程可以用来加密编译时常量数据吗?
让我用一个例子来解释我的意思。假设我记录了有关失败代码行的信息,如下所示:
if (index > MaxIndex) { Log(__FILE__); abort(); }
是否有可能(使用模板元编程或其他魔法)编写Log()
以便替换的编译时常量字符串__FILE__
被加密,以便二进制中使用的实际数据是编译时加密字符串?如果不是,为什么?
你的假设是不正确的。C99 仅定义__func__
,但 GCC 提供__FUNCTION__
和__PRETTY_FUNCTION__
作为扩展,其行为相同。它们都不是宏,而是标识符。例如 C11,6.4.2.2:
标识符
__func__
应由翻译器隐式声明,就好像紧跟在每个函数定义的左大括号之后,声明static const char __func__[] = "function-name";
出现,其中function-name是词法封闭函数的名称
不幸的是,在 C++11 中,static const char []
不是常量表达式,因此上述标识符都不能用作模板元程序参数。
(相比之下,__FILE__
and__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__
不是常量表达式的内容。