Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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++_Gcc_Optimization_Visual C++_Clang - Fatal编程技术网

C++ 匿名名称空间中的全局变量优化

C++ 匿名名称空间中的全局变量优化,c++,gcc,optimization,visual-c++,clang,C++,Gcc,Optimization,Visual C++,Clang,以下是一个例子: 名称空间{ int a=0; } int main{ a=1; } 优化了a=1,但没有 GCC的输出示例: main: xor eax, eax ret main: add DWORD PTR _ZN12_GLOBAL__N_11aE[rip], 1 xor eax, eax ret 另一个例子: 名称空间{ int a=0; } int main{ a++; } 没有

以下是一个例子:

名称空间{ int a=0; } int main{ a=1; } 优化了a=1,但没有

GCC的输出示例:

main:
        xor     eax, eax
        ret
main:
        add     DWORD PTR _ZN12_GLOBAL__N_11aE[rip], 1
        xor     eax, eax
        ret
另一个例子:

名称空间{ int a=0; } int main{ a++; } 没有一个编译器优化了++:

GCC的输出示例:

main:
        xor     eax, eax
        ret
main:
        add     DWORD PTR _ZN12_GLOBAL__N_11aE[rip], 1
        xor     eax, eax
        ret

为什么编译器会优化某些全局变量,但不会优化其他变量,这有什么道理吗?可以为特定的编译器提供答案。

对于第一个示例,如果您使用/GL标志,MSVC还将优化全局编译器并将其写入。不幸的是,当您这样做时,它不会生成汇编语言输出,所以Godbolt只会告诉您输出文件丢失。要检查代码,您必须生成一个实际的可执行文件,然后将其反汇编,以获得:

0000000140001000: 33 C0              xor         eax,eax
0000000140001002: C3                 ret
…但即使是/GL也不会优化第二种情况下的增量:

0000000140001000: FF 05 AA 6B 01 00  inc         dword ptr [0000000140017BB0h]
0000000140001006: 33 C0              xor         eax,eax
0000000140001008: C3                 ret
原因很难回答,因为它归结于从事编译器优化工作的人们的动机。然而,我猜,他们大多至少对顾客感知到的需求做出反应。因此,对于gcc来说,很多问题都归结为特定的优化是否会显著地帮助或损害流行的开源软件包(如Linux)的性能。同样,对于MSVC来说,它主要是关于流行的软件包,比如Windows和Office,不,我并不是说他们也忽略了他们的外部客户

因此,在本例中,当程序启动时,代码的影响很小。那么,最大的问题是,这是否会对其他足够常见的代码产生更大的影响,从而使他们有动力对其进行优化。我想至少到目前为止,他们还没有看到出现这种情况的案例。考虑到大多数人创建和初始化全局变量的频率,并从那时起忽略它,我的猜测是,他们根本看不出有多少理由处理这种特殊情况。它的优化程度仅限于其相似程度,足以受他们主要为其他情况编写的优化的影响。例如,如果在此常规订单上添加对的另一个修改:

名称空间{ int a=0; } 福娃 {
对于int i=0;i对于第一个示例,如果您使用/GL标志,MSVC还将优化全局文件并写入其中。不幸的是,当您这样做时,它不会生成汇编语言输出,因此Godbolt只会告诉您缺少输出文件。要检查代码,您必须生成一个实际的可执行文件,然后将其反汇编,以获得:

0000000140001000: 33 C0              xor         eax,eax
0000000140001002: C3                 ret
…但即使是/GL也不会优化第二种情况下的增量:

0000000140001000: FF 05 AA 6B 01 00  inc         dword ptr [0000000140017BB0h]
0000000140001006: 33 C0              xor         eax,eax
0000000140001008: C3                 ret
原因很难回答,因为这归结于从事编译器优化工作的人的动机。然而,我猜他们主要是响应客户至少感知到的需求。因此,对于gcc来说,很多问题归结于特定优化是否会显著帮助或损害编译器的性能流行的开源软件包,如Linux。同样,对于MSVC来说,主要是关于流行的软件包,如Windows和Office,不,我不是说他们也忽略了他们的外部客户

因此,在这种情况下,当程序启动时,代码的影响很小。接下来的大问题是,这是否会转化为对其他代码的更大影响,这些代码足够常见,以至于他们会有一些动机对其进行优化。我想至少到目前为止,他们还没有看到出现这种情况的情况。考虑到n大多数人创建并初始化一个全局变量,然后从那时起忽略它,我的猜测是,他们根本看不出有多少理由处理这个特殊情况。它的优化程度仅限于其相似程度,足以受到他们主要为其他情况编写的优化的影响。例如,如果您添加对,根据这项一般命令:

名称空间{ int a=0; } 福娃 {
对于int i=0;ito Optimization or not不是T语言的一部分,因此每个编译器都可以自由地进行它想要的优化,同时它们也不会与语言规则不兼容。因此,与其问编译器为什么不这样做,不如问从事编译器工作的人为什么不这样做,为什么你不问问自己为什么要编写这种代码?为什么要抗议和询问其他人优化你糟糕的代码,而不是不这样编码?请不要说这句话不好,只是为了让我的句子更清楚。还有,参加编译器实现怎么样?@cpp编译器是一个和其他程序一样的程序,他们做事情,不做其他。潜在的选项列表mizations是无限的,而开发它们的时间和工作人员的数量都是无限的,那么根据定义,所有潜在的优化都没有完成。无论如何,已经完成的优化列表是难以置信的,请确保您不知道这个列表这么长,我想
t是。。。也没有me@CPPCPPCPPCPPCPPCPPCPPCPPCPPCPP一般来说,这可能没有那么明显。私有全局变量可以在main之外使用,而编译器要证明相反的结果可能并不那么容易。在我看来,这只是一个错过的优化。还有许多其他的组合确实得到了优化。注:它也可以用静态int a复制;我会注意到a=1执行写操作,但不执行读操作,所以编译器可能已经意识到了这一点。另一方面,a++执行读和写操作,编译器似乎没有注意到,唯一的读操作永远不会逃逸,它们只用于编写变量。优化与否不是语言的一部分,因此每个编译器都可以自由地进行它想要的优化,而不会与语言规则不兼容。出于这一点,而不是问为什么编译器没有,所以从事编译器工作的人没有,为什么你不问自己为什么要编写这种代码?为什么要抗议并要求其他人优化你糟糕的代码,而不是不这样编码?请不要把那句话说得太糟,只是为了让我的句子更清楚。还有,参加编译器实现怎么样?@cpp编译器是一个程序,与其他程序一样,他们做事情,不做其他事情。潜在优化的列表是无限的,而开发它们的时间和工作人员的数量是无限的,那么根据定义,所有潜在优化都没有完成。无论如何,已经完成的优化列表是难以置信的,请确保您不知道该列表如此之长。。。也没有me@CPPCPPCPPCPPCPPCPPCPPCPPCPPCPP一般来说,这可能没有那么明显。私有全局变量可以在main之外使用,而编译器要证明相反的结果可能并不那么容易。在我看来,这只是一个错过的优化。还有许多其他的组合确实得到了优化。注:它也可以用静态int a复制;我会注意到a=1执行写操作,但不执行读操作,所以编译器可能已经意识到了这一点。另一方面,a++执行读和写操作,编译器似乎没有注意到,只读永远不会转义,它们只用于编写变量。