奇怪的GCC行为

时间:2011-10-06 03:39:12

标签: c++ gcc compiler-construction g++ c++11

给出以下C ++代码:

struct vertex_type {
    float x, y, z;

    //vertex_type() {}
    //vertex_type(float x, float y, float z) : x(x), y(y), z(z) {}
};

typedef struct {
    vertex_type vertex[10000];
} obj_type;

obj_type cube = {
    {
        {-1, -1, -1},
        {1, -1, -1},
        {-1, 1, -1},
        {1, 1, -1},

        {-1, -1, 1},
        {1, -1, 1},
        {-1, 1, 1},
        {1, 1, 1}
    }
};

int main() {
    return 0;
}

当我将(当前已注释掉的)构造函数添加到vertex_type结构中时,编译时间突然增加10-15秒。 难倒,我查看了gcc生成的程序集(使用-S),发现代码大小比以前大了几百倍。

...
movl    $0x3f800000, cube+84(%rip)
movl    $0x3f800000, cube+88(%rip)
movl    $0x3f800000, cube+92(%rip)
movl    $0x00000000, cube+96(%rip)
...
movl    $0x00000000, cube+119996(%rip)
...

通过省略构造函数定义,生成的程序集完全不同。

.globl cube
    .data
    .align 32
    .type   cube, @object
    .size   cube, 120
cube:
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .zero   24
    .text

显然,编译器生成的代码存在显着差异。 这是为什么? 另外,为什么gcc在一种情况下归零所有元素而不是另一种情况?

修改 我使用以下编译器标志:-std=c++0x与g ++ 4.5.2。

2 个答案:

答案 0 :(得分:14)

这是一个长期存在的missing optimization in GCC。它能够为两种情况生成相同的代码,但它不能。

没有构造函数,您的vertex_type是一个POD结构,GCC可以在编译时初始化静态/全局实例。使用构造函数,它可以做的最好的事情是生成代码以在程序启动时初始化全局。

答案 1 :(得分:0)

如果你有自定义构造函数,编译器应该为它创建的所有向量调用它。如果您不编写自己的,则默认为生成的构造函数。但由于没有类型是复杂的,它只是不需要调用它。并且数组作为二进制中的常量表存储。

尝试内联默认构造函数并将其清空。当然,它可能仅在启用优化时起作用