使用专用模板进行g ++错误优化

时间:2015-10-31 04:04:24

标签: templates c++11 gcc optimization

我遇到了g ++(4.9.2)优化的问题,这会产生令我困惑的错误代码。而且由于错误,我的意思是优化(-O1,-O2或-O3)和非优化(-O0)编译之间的代码输出是有趣的。当然,优化的代码是错误的。

我的类与<bitset>类似,其中info存储在位级并且使用任意数量的位进行实例化,但是具有用于&lt; = 8位的位的专用模板。

#include <iostream>
using namespace std;

// generalized class Bits, uses array of specialized, 1-byte Bits
template <unsigned int bits=8, bool _=(bits>8)>
class Bits {
    Bits<8,false> reg[(bits+7)>>3];

public:
    void set(int pos)  { reg[pos>>3].set(pos%8);  };
    void clr(int pos)  { reg[pos>>3].clr(pos%8);  };
    bool get(int pos)  { reg[pos>>3].get(pos%8);  };
};

// specialized, 1-byte Bits (flag stored in a char)
template <unsigned int bits> class Bits<bits,false> {
    char reg;

public:
    Bits() : reg(0) {};
    Bits(int r) : reg(r) {};

    void set(int pos) { reg |=  mark(pos);        };
    void clr(int pos) { reg &= ~mark(pos);        };
    bool get(int pos) { return (reg & mark(pos)); };

    static int mark(int pos) { return ( 1 << pos ); };
};  


int main() {
    Bits<16> b;
    Bits<8> c;

    b.set(1);
    c.set(1);

    cout << b.get(1) << endl;
    cout << c.get(1) << endl;

    return 0;
};

测试很简单,设置一点,然后将所述位状态打印到stdout。这是通过16位Bits对象(广义模板化)和8位Bits对象(专用模板)完成的。对于任一对象,预期答案为TRUE。当我编译没有优化(即g++-4.9 -O0 main.cpp)时,这正是我得到的。 ./a.out的输出为:

1
1

但是当我使用-O1优化(即g++-4.9 -O1 main.cpp)进行编译时,结果会有所不同且部分错误:

0
1

具体来说,Bits<8>在优化(-O0和-O3)中都能正确测试,但Bits<16>仅使用-O0而不是-O1正确测试。

优化器(-O1,-O2和-O3)都只是优化了所有Bits成员函数,并简单地跳转到在编译时计算的最终结果。显然优化器出现了一些错误,但我不知道根本原因是什么。有谁知道我应该寻找什么来调试问题?

2 个答案:

答案 0 :(得分:3)

当返回bool的函数有一个return语句时,它通常会有所帮助:

    bool get(int pos)  { return reg[pos>>3].get(pos%8);  };
                         ^^^^^^

有了这个:

$ g++ -O3 foo.cpp
$ ./a.out
1
1

答案 1 :(得分:1)

@Adam是对的, -Wall说全部:

test.cpp: In member function ‘bool Bits<bits, _>::get(int)’: test.cpp:12:51: warning: no return statement in function returning non-void [-Wreturn-type] bool get(int pos) { reg[pos>>3].get(pos%8); };