为什么常见的c ++编译器不能优化对象副本?

时间:2017-09-15 16:30:26

标签: c++ optimization c++14

我有以下来源:

#include <iostream>
struct A{
    int data[10000]; // A large data field
    void print() const{
        for(int i=0;i<100;i++){
            std::cout<<data[i]<<",";
        }
        std::cout<<std::endl;
    }
};
struct B{
    A data;
    void print() const{
        for(int i=0;i<100;i++){
            std::cout<<data.data[i]<<" ";
        }
        std::cout<<std::endl;
    }
};


int main(){
    A a;
    a.data[50]=10;
    a.data[60]=5;
    a.data[70]=3;
    a.print();
    B b{a};
    b.print();          
}

它在A中保存一个大数据字段,将其放入B中,然后执行其成员函数。现在,由于B没有除A以外的任何其他数据字段,我认为编译器实际上可以优化掉副本并只重用相同的数据块,执行不同的成员函数。但是,根据https://godbolt.org/g/21z7TT,最新版本的g ++和clang -O3编译选项都不会优化memcpy。有没有理由不能优化这个代码,有没有办法让编译器优化它?

1 个答案:

答案 0 :(得分:3)

它并没有优化掉副本,因为你确实指示它制作副本。 struct B { A data; ... };表示B包含自己的A结构副本。

在这个特殊的微型程序中,编译器理论上可以使用相同的内存而不会产生任何后果。但是,如果有很多事情发生变化,那么这种能力就会消失:

  • a再次使用
  • B包含A
  • 以外的所有数据成员
  • b被传递给另一个函数
  • 我想不到的其他人。

鉴于这种优化的条件有多么罕见,我并不感到惊讶,因为没有特殊的编译器案例。