我遇到了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成员函数,并简单地跳转到在编译时计算的最终结果。显然优化器出现了一些错误,但我不知道根本原因是什么。有谁知道我应该寻找什么来调试问题?
答案 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); };