1

Are those constant arrays allocates space in memory or compilers are smart enough and decays this into something literal?

I will just provide an example here:

const int array[] = {
    1, 2, 3, 4, 5
};

Well, I just wanted to know nothing else.

4

5 回答 5

2

简短的回答是:这取决于。

长答案是:

如果你编译这个:

const int array[] = {
   1, 2, 3, 4, 5
};

int
main()
{
   return array[0];
}

你最终在 x86/Linux(简化)上得到了这个:

       .globl  main
main:
       movl    $1, %eax
       ret

所以是的,它不会存储在任何地方,而是被视为在编译时评估的常量。

但是,如果您这样使用它:

const int array[] = {
   1, 2, 3, 4, 5
};

int
main()
{
   return (long)array;
}

它成为了:

        .globl  main
main:
        leal    _ZL5array(%rip), %eax
        ret
        .section        .rodata
        .align 16
_ZL5array:
        .long   1
        .long   2
        .long   3
        .long   4
        .long   5

它在 rodata 部分结束,因为你告诉编译器你实际上需要它作为一个数组。

于 2013-05-29T10:53:06.173 回答
0

Qt 背后的专家之一 Olivier Goffart有一篇关于 C++ 中数据初始化的优秀博客文章。

于 2013-05-29T10:18:01.670 回答
0

优化器实际上是非常聪明的生物。例如,这段代码:

const int array[] = {1, 2, 3, 4, 5};

void show(int i)
{
    printf("%d\n", i);
}

int main(int argc, char * argv[])
{
    show(array[0]);
}

很可能最终会变成:

void show()
{
    printf("%d\n", 1);
}

int main(int argc, char * argv[])
{
    show();
}

我猜,那个优化器会注意到,那个节目可能很容易被内联,所以代码可能会被进一步优化:

int main(int argc, char * argv[])
{
    printf("%d\n", 1);
}
于 2013-05-29T10:23:41.940 回答
0

从理论上讲,这完全取决于实施。C++ 标准定义了你得到的行为——你如何得到它留给魔法。

在实践中,我希望每个编译器(平台支持它)在编译时将该数组放在一个 const 段中,并直接从那里使用它。

随着优化器的进行,在前面创建的“const”对象的状态是固定的(标准使得通过任何方式更改它们的行为都是未定义的),并且数据流分析器会考虑到这一点。从已知位置从数组中读取值可以并且通常由数字代替。

此外,使用顶级 const 的 IIRC 默认情况下使对象静态,因此除非您使用“extern”,否则它将在翻译单元中是私有的。如果代码中没有任何东西真的需要它(获取是按值内联的),它根本不会被发出。

大多数编译器都可以选择发出汇编/机器代码输出,以便您可以检查它对特定实现的作用,或者您可以使用目标文件转储器来查看数组的存在。

于 2013-05-29T10:29:47.727 回答
0

我相信它们可以很容易地优化,如果它们是static. 用一些技巧(比如const_casting 它)改变它们的值是未定义的行为,所以编译器不会关心。无论如何 - 你可以检查。gcc -O2 -S temp.c.

如果数组是全局的而不是全局static的,编译器应该保留它以防其他编译单元需要它。除非您进行整个程序优化。

于 2013-05-29T10:19:26.500 回答