Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内联和死代码删除优化能否阻止模板实例化?_C++_Templates_Optimization_Dead Code_Inlining - Fatal编程技术网

C++ 内联和死代码删除优化能否阻止模板实例化?

C++ 内联和死代码删除优化能否阻止模板实例化?,c++,templates,optimization,dead-code,inlining,C++,Templates,Optimization,Dead Code,Inlining,给出以下示例代码 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

给出以下示例代码

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是一个模板类,其成员f和g仅在被引用时实例化。f在main中引用。如果我不引用内部试图使用不完整类型的g,代码将编译。但是g在f中的if分支中被引用。此分支绝对不会被执行。因此,编译器可能会忽略/删除这个死代码分支,从而避免g的实例化以及尝试使用不完整类型的错误。然而,至少在我尝试过的编译器上没有发生这种情况

我知道,允许这样做只需调整编译器的优化设置,就可以将非法代码转化为合法代码,但我的问题是,这个代码示例是否会因为某些规则而注定失败,例如优化顺序与模板传递,这些规则可以在某个地方阅读


谢谢您的见解。

优化是允许编译器应用于有效程序的东西。由于S未定义,因此无法实例化,并且您的程序无效。对于优化器来说,让程序生效为时已晚

内联和死代码删除优化能否阻止模板实例化

没有

死代码删除是一种优化,可以根据优化程序的规则删除未使用的代码。只要实现希望保持完全符合,此类优化可能不会违反“好像”规则

无论如何,这个程序的格式是错误的。在main中找到的调用需要完全实例化C,这是不可能的。如果这个实例化成功了,那么它的未使用部分可能已经被优化掉了,但这是后面的一步。您只能删除一个程序的未使用部分,而该部分本来是物理上可以存在的

询问是否需要实现来防止编译这样一个格式错误的程序可能很有趣,如果它以后可能会删除有问题的代码。我们可以通过引用标准中定义格式不良†的任何段落来轻松回答这一问题。但这是一个不同的问题,在我看来,顺便提一下


†如果您感兴趣,我们无法在一般情况下以肯定的方式回答此问题,因为某些不符合条件的情况会被限定为“无需诊断”。然而,如果我不知道这个短语,就需要进行诊断。不要让我这么做。

C++标准从来都不会保证失败。它只要求正确的程序产生与执行模型一致的结果。在某些情况下,它确实需要诊断信息;我不认为这是一个这样的情况,但我可能是错的。你的问题与标题Lolbutttt相反,完整地说,它很可能构建并运行得很愉快。我意识到这不是要求的。一个有效的程序和一个运行良好的程序是两码事。许多程序依赖于可预测的未定义行为。想想那些未初始化的变量,它们没有不良影响99.9999%的时候这些程序是无效的,编译器可以随心所欲地做任何事情,包括格式化你的硬盘,但实际上它们运行得很好。关于你的第二段:如果我删除对g的调用,程序就不是格式不良的,尽管g的格式错误的实现仍然存在于C中。据我所知,C的实例化并不要求它的全部是有效的,它只要求它的引用成员是有效的。这就是我的问题的基础:由于g只在代码中未使用的部分引用,编译器是否仍然需要检查其理论有效性,即使它是一个模板类成员函数?我看到,似乎规则和标准对格式错误的定义基本上就是答案,我将在这些方面做一些研究。谢谢。C的实例化并不要求它的全部都是有效的,我想是的。