Alw*_*sed 4 c++ template-meta-programming c++11 c++14
请考虑以下代码,该代码具有无法访问的无法访问undefinedFunction.
void undefinedFunction();
template <bool b = false>
void foo()
{
static_assert(b == false);
if (b)
undefinedFunction();
}
int main()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
GCC在没有投诉的情况下编译和链接.有了static_assert,很难看出编译器如何做出不同的事情,但标准对此有什么要说的吗?如果static_assert删除怎么办?编译器是否有义务删除分支,或者它实际上是否会发出一条无法访问的调用指令,这会导致链接器抱怨?
通常情况下,调用一个函数ODR-使用它,但有两个例外:如果是纯虚拟的,或者如果它不可能进行评估([basic.def.odr]/5).除非表达式是未评估的操作数或其子表达式([basic.def.odr]/2),否则可能会对表达式求值.发生在未计算的操作数typeid,sizeof,noexcept,和decltype,其中没有一个适用于这里.因此undefinedFunction只要foo实例化就是odr-used ,它就是."静态无法访问"代码也不例外.
根据 C++ 标准\xc2\xa73.2/p4 单一定义规则 [basic.def.odr] (强调我的):
\n\n\n\n\n每个程序都应包含该程序中使用的每个非内联函数或变量的精确定义;无需诊断。该定义可以显式地出现在程序中,可以在标准或用户定义的库中找到,或者(在适当的情况下)它是隐式定义的(参见 12.1、12.4 和 12.8)。内联函数应在每个使用 ODR 的翻译单元中定义。
\n
foo实例化的模板函数是odr-used(即需要undefinedFunction定义)。如果子句不被评估也undefinedFunction没关系。if因此,该程序格式不正确,并且由于不需要诊断,因此它可能会链接,也可能不会链接。