STL push_back优化导致数组下标高于数组边界

时间:2014-07-31 02:11:01

标签: c++ stl g++

测试环境:

  • CentOS 7.0 g ++ 4.8.2
  • Arch Linux g ++ 4.9.0 20140604(预发布)
  • Arch Linux g ++ 4.9.1

编译命令案例:

  1. 通过:g ++ -Wall t.cpp
  2. 失败:g ++ -Wall -O2 t.cpp
  3. 通过:g ++ -Wall -O2 t.cpp#并在第13行将3替换为3
  4. 通过:g ++ -Wall -O2 t.cpp#并注释掉第14行
  5. 通过:g ++ -Wall -O2 --std = c ++ 11 t.cpp#for g ++ 4.8 / 4.9
  6. 失败的消息:

    t.cpp: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vecto
    <_Tp, _Alloc>::iterator, const _Tp&) [with _Tp = Object; _Alloc = std::allocator<Ob
    ject>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Object*, s
    td::vector<Object> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Object*]’
    t.cpp:17:15: warning: array subscript is above array bounds [-Warray-bounds]
         ~Object() {};
                   ^
    t.cpp:17:15: warning: array subscript is above array bounds [-Warray-bounds]
    

    t.cpp

    #include <vector>                      
    class TestCls {                        
    public:                                
        TestCls() {};                      
        virtual ~TestCls() {};             
    };                                     
    class TestCls1 : public TestCls        
    {                                      
    };                                     
    class Object {                         
    public:                                
        TestCls    m_member[2];            
        TestCls1   m_member1[2]; // LINE 13, if change to [3] it works.
        TestCls1   m_member2[2]; // LINE 14, if comment out this line, it works.
    
        Object() {};                       
        ~Object() {}; // LINE 17 the warning line                     
    };                                     
    class Container {                      
    public:                                
        std::vector<Object> m_obj;         
    
        Container() {};                    
        ~Container() {};                   
    };                                     
    int main() {                           
            Container con;                 
            Object obj;                    
            con.m_obj.push_back(obj);      
    }                                      
    

3 个答案:

答案 0 :(得分:0)

这是由GCC生成的一种虚假警告,由于值范围传播(生成数组边界警告的中端传递)与各种循环优化器传递(例如循环剥离和循环展开)交互的问题。正如各种bugzillas linked中提到的那样,这些也代表了错过的优化机会,但是对于GCC开发人员而言,VRP中的潜在问题(或问题)已经证明是难以捉摸的。也就是说,将此事件报告给GCC Bugzilla是一个好主意,特别是因为您手头有一个MWE。

答案 1 :(得分:0)

我找到了解决方案,但我不知道原因。

// ...
class Object {
public:
    // ...
    ~Object();
};
Object::~Object() {}; // move to outside LINE 19
//...

答案 2 :(得分:-1)

  

gcc -Wall启用所有编译器的警告消息。这个选项应该   总是被使用,以生成更好的代码。

所以,试试删除-Wall。例如: