Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++;可执行文件?_C++_C - Fatal编程技术网

C++ 哪个部分将全局常量变量存储在C++;可执行文件?

C++ 哪个部分将全局常量变量存储在C++;可执行文件?,c++,c,C++,C,据我所知,在C/C++程序中,全局常量变量将存储在可执行文件的.text(或.data-我不确定)部分。但当我试图验证这一点时,我遇到了麻烦 我有一个程序,它有一个全局常量变量,如下所示: const unsigned char data[2030320] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x04, 0x00, 0x30, 0x42, 0x41, 0x53, 0x45, 0xda, 0xec, 0

据我所知,在C/C++程序中,全局常量变量将存储在可执行文件的.text(或.data-我不确定)部分。但当我试图验证这一点时,我遇到了麻烦

我有一个程序,它有一个全局常量变量,如下所示:

const unsigned char data[2030320] =
{
    0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x04, 0x00, 0x30, 0x42, 0x41, 0x53, 0x45,
    0xda, 0xec, 0xe7, 0xed, 0x00, 0x00, 0x01, 0x3c, 0x00, 0x00, 0x00, 0xc6, 0x47, 0x44, 0x45, 0x46,
    0x50, 0x4b, 0x6e, 0x76, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x4e, 0x47, 0x50, 0x4f, 0x53,
    0x64, 0x0a, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x0a, 0xdc, 0x47, 0x53, 0x55, 0x42,
    0x41, 0xfc, 0x50, 0x71, 0x00, 0x00, 0x0d, 0x30, 0x00, 0x00, 0x44, 0x16, 0x4c, 0x49, 0x4e, 0x4f,
    0x96, 0xa8, 0xc8, 0xcc, 0x00, 0x00, 0x51, 0x48, 0x00, 0x00, 0x00, 0x12, 0x4f, 0x53, 0x2f, 0x32,
    0x63, 0x8d, 0x51, 0xdd, 0x00, 0x00, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6d, 0x61, 0x70,
    0xc7, 0xfa, 0x84, 0xe4, 0x00, 0x00, 0x51, 0xbc, 0x00, 0x00, 0x8c, 0xf2, 0x67, 0x61, 0x73, 0x70,
    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xde, 0xb0, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6c, 0x79, 0x66,
    0x31, 0xb9, 0x1a, 0xce, 0x00, 0x00, 0xde, 0xb8, 0x00, 0x1b, 0x4e, 0x90, 0x68, 0x65, 0x61, 0x64,
    0xfe, 0x4d, 0xbc, 0xcd, 0x00, 0x1c, 0x2d, 0x48, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
    0x07, 0x6b, 0x21, 0x2a, 0x00, 0x1c, 0x2d, 0x80, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
    0x04, 0x8c, 0x39, 0x67, 0x00, 0x1c, 0x2d, 0xa4, 0x00, 0x00, 0x7b, 0xf4, 0x6c, 0x6f, 0x63, 0x61,
    0x72, 0x06, 0x3f, 0xca, 0x00, 0x1c, 0xa9, 0x98, 0x00, 0x00, 0x7b, 0xf8, 0x6d, 0x61, 0x78, 0x70,
    0x21, 0x89, 0x01, 0x63, 0x00, 0x1d, 0x25, 0x90, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
    0xc0, 0xe5, 0xda, 0x3d, 0x00, 0x1d, 0x25, 0xb0, 0x00, 0x00, 0x04, 0x3d, 0x70, 0x6f, 0x73, 0x74,
    0x0a, 0xfb, 0xdd, 0xeb, 0x00, 0x1d, 0x29, 0xf0, 0x00, 0x01, 0x54, 0xe2, 0x70, 0x72, 0x65, 0x70,
...
};
但当使用dumpbin.exe(在Windows上)检查程序的.exe文件中节的大小时。如果我删除变量,结果与结果相同,它总是如下所示

  4B1000 .data
    1000 .idata
    3000 .rdata
    2000 .reloc
    1000 .rsrc
    4000 .text
   10000 .textbss

有谁能帮我解释一下吗?

如果能证明变量从未被引用,编译器很可能会优化掉变量。不幸的是,编译器一次只能看到一个翻译单元(包含在
#include
之后的源文件),因此禁止编译器优化未使用的全局变量。链接器拥有所有转换单元的知识,因此它可以(并且将)对未使用的全局变量执行优化

以下代码使用MSVC编译(
/O2
指定):

创建以下PE文件:

File Type: EXECUTABLE IMAGE

  Summary

        1000 .data
        1000 .gfids
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text
如果使用全局,则它将存储在PE文件的
.rdata
段中(注意,如果全局为非常量,则它将被放置在
.data
段中,因为
.rdata
是只读的)。例如:

const char a[1000000] = { 0 };

int main()
{
    char c = a[1];
    return 0;
}
dumpbin
输出:

File Type: EXECUTABLE IMAGE

  Summary

        1000 .data
        1000 .gfids
       F5000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text
但是在下面的示例中,
a
仍然可以优化,因为
c
是未引用的局部变量。我发现,在MSVC
/GS
中,编译器开关(它表示整个程序优化,并强制执行
/LTCG
,它将代码生成延迟到链接阶段,以便执行跨文件优化的所有信息都可用)实际上阻止了这种优化


在没有
/LTCG
/GS
的情况下,它按预期进行了优化。添加
/GS
将禁用全局数据优化,必须通过添加
/Gw

来启用全局数据优化,如果数据未在任何地方使用,则生成的文件甚至不需要包含数据-编译器或链接器可以删除它。您是对的。我已经确认了。但是如果全局变量是const,则它是正确的。如果我将数据[]从常量更改为非常量,即使未使用,它也始终存储在.data中。你能帮我解释一下吗?常量不能进入
。data
,因为它们是只读的-
。rdata
表示PE规范中规定的“只读初始化数据”。编译器可能无法优化未使用的非常量全局变量。对我来说(MSVC),未使用的非常量全局值不能进入PE。听到编译器在第二个示例中没有优化数组,我感到震惊。@MikeMB我很欣赏讽刺。移除了那个不幸的sentence@mpiatek:一点也不讽刺。我真的希望编译器能够优化全局数组,即使您以示例中所示的方式使用它,因为这种用法本身是可以删除的。
File Type: EXECUTABLE IMAGE

  Summary

        1000 .data
        1000 .gfids
       F5000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text