内联和死代码删除优化能否阻止模板实例化?
Can inlining and dead code removal optimizations prevent template instantiations?
给定以下示例代码
struct S;
template<typename>
class C
{
public:
void f(bool b)
{
if (b)
g();
}
void g()
{
S{};
}
};
int main()
{
C<int>{}.f(false);
}
GCC 正确报告以下内容:
example.cpp: In instantiation of 'void C< <template-parameter-1-1> >::g() [with <template-parameter-1-1> = int]':
10 : required from 'void C< <template-parameter-1-1> >::f(bool) [with <template-parameter-1-1> = int]'
21 : required from here
15 : error: invalid use of incomplete type 'struct S'
我现在的问题是:这种保证行为是否在标准或任何其他文件中有一些规定?
更准确地说我的问题:
C
是一个模板class,其成员f()
和g()
仅在被引用时实例化。 f()
在 main()
中被引用。如果我不引用 g()
(它在内部尝试使用不完整的类型),代码将编译。但是 g()
在 f()
内的 if 分支中被引用。该分支确定性地永远不会被执行。因此,编译器可能会 ignore/remove 这个死代码分支,从而避免 g()
的实例化(以及尝试使用不完整类型的错误)。然而,这并没有发生(至少在我尝试过的编译器上)。
我知道允许这样做只会通过调整编译器的优化设置将非法代码变成合法代码,但我的问题仍然是这个代码示例是否由于某些规则(例如优化顺序与. 模板通过),可以在某处阅读。
感谢您的任何见解。
优化是允许编译器应用于有效程序的东西。由于 S 未定义,因此无法实例化,您的程序无效。优化器来不及使程序有效。
Can inlining and dead code removal optimizations prevent template instantiations?
没有
死代码删除是一种优化,可以根据优化器的规则删除不是 "used" 的代码。只要实施希望保持完全合规,此类优化就不会违反 "as-if" 规则。
这个程序无论如何都是错误的。 C<int>
的实例化完全是由 main
中的调用要求的……这是不可能的。如果此实例化成功,那么它未使用的部分可能已被优化掉,但这是一个步骤 "later"。您只能删除程序中未使用的部分,这些部分首先在物理上能够 "existing"。
询问是否需要实现来防止编译这种格式错误的程序可能很有趣,如果以后可能会删除有问题的代码的话。我们可以通过引用标准定义 "ill-formed"† 的任何段落来轻松回答这个问题。但这是一个不同的问题,而且在我看来,顺便提一下。
† 如果你有兴趣,我们不能在一般情况下肯定地回答这个问题,因为一些不合规的情况是合格的用短语 "no diagnostic required"。但是,如果不存在该短语,则需要诊断 。 (别逼我。)
给定以下示例代码
struct S;
template<typename>
class C
{
public:
void f(bool b)
{
if (b)
g();
}
void g()
{
S{};
}
};
int main()
{
C<int>{}.f(false);
}
GCC 正确报告以下内容:
example.cpp: In instantiation of 'void C< <template-parameter-1-1> >::g() [with <template-parameter-1-1> = int]':
10 : required from 'void C< <template-parameter-1-1> >::f(bool) [with <template-parameter-1-1> = int]'
21 : required from here
15 : error: invalid use of incomplete type 'struct S'
我现在的问题是:这种保证行为是否在标准或任何其他文件中有一些规定?
更准确地说我的问题:
C
是一个模板class,其成员f()
和g()
仅在被引用时实例化。 f()
在 main()
中被引用。如果我不引用 g()
(它在内部尝试使用不完整的类型),代码将编译。但是 g()
在 f()
内的 if 分支中被引用。该分支确定性地永远不会被执行。因此,编译器可能会 ignore/remove 这个死代码分支,从而避免 g()
的实例化(以及尝试使用不完整类型的错误)。然而,这并没有发生(至少在我尝试过的编译器上)。
我知道允许这样做只会通过调整编译器的优化设置将非法代码变成合法代码,但我的问题仍然是这个代码示例是否由于某些规则(例如优化顺序与. 模板通过),可以在某处阅读。
感谢您的任何见解。
优化是允许编译器应用于有效程序的东西。由于 S 未定义,因此无法实例化,您的程序无效。优化器来不及使程序有效。
Can inlining and dead code removal optimizations prevent template instantiations?
没有
死代码删除是一种优化,可以根据优化器的规则删除不是 "used" 的代码。只要实施希望保持完全合规,此类优化就不会违反 "as-if" 规则。
这个程序无论如何都是错误的。 C<int>
的实例化完全是由 main
中的调用要求的……这是不可能的。如果此实例化成功,那么它未使用的部分可能已被优化掉,但这是一个步骤 "later"。您只能删除程序中未使用的部分,这些部分首先在物理上能够 "existing"。
询问是否需要实现来防止编译这种格式错误的程序可能很有趣,如果以后可能会删除有问题的代码的话。我们可以通过引用标准定义 "ill-formed"† 的任何段落来轻松回答这个问题。但这是一个不同的问题,而且在我看来,顺便提一下。
† 如果你有兴趣,我们不能在一般情况下肯定地回答这个问题,因为一些不合规的情况是合格的用短语 "no diagnostic required"。但是,如果不存在该短语,则需要诊断 。 (别逼我。)