我在使用GCC(版本为4.6.4,Ubuntu 12.04)编译一个大型项目(数百个文件和数十万行代码)时,遇到了一个奇怪的问题。最近我发现,在某些编译过程中(似乎是随机的),我会得到一段特定的代码编译结果与预期不同,导致我的代码出现未定义的行为:
但这不是问题所在。真正的问题是成员someOtherMember的偏移量,0x278c是正确的(第一个情况),但0x27d4是错误的(第二个情况),这显然会修改类中完全不同的成员。为什么会发生这种情况?我漏掉了什么?(另外,我不知道还能发布哪些相关信息,请问一下)。请记住,这种情况在重新编译项目时发生(全面重新编译或仅编译已修改的文件),而且在不修改受影响的文件(或使用的类文件)的情况下发生。例如,在完全无关的文件中添加一个简单的printf()语句可能会触发此行为,或者在发生时会使其消失。 我应该把这归咎于-O2吗?因为这种情况完全是随机发生,所以我无法在没有优化标志的情况下重现它。 我正在使用make -j 8,即使清理构建文件夹后也会发生这种情况,但不一定只有在这种情况下才会发生。
class someDerivedClass : public someBaseClass
{
public:
struct anotherDerived : public anoterBaseClass
{
void SomeMethod()
{
someMember->someSetter(2);
}
}
}
"someSetter"的定义如下:
void someSetter(varType varName) { someOtherMember = varName; }
通常,SomeMethod() 会被编译为:
00000000019fd910 mov 0x20(%rdi),%rax
00000000019fd914 movl $0x2,0x278c(%rax)
00000000019fd91e retq
但有时它会被(错误地)编译为:
000000000196e4ee mov 0x20(%rdi),%rax
000000000196e4f2 movl $0x2,0x27d4(%rax)
000000000196e4fc retq
由于编译标志-O2,setter似乎被内联了:
-std=c++11 -m64 -O2 -ggdb3 -pipe -Wliteral-suffix -fpermissive -fno-fast-math -fno-strength-reduce -fno-delete-null-pointer-checks -fno-strict-aliasing
但这不是问题所在。真正的问题是成员someOtherMember的偏移量,0x278c是正确的(第一个情况),但0x27d4是错误的(第二个情况),这显然会修改类中完全不同的成员。为什么会发生这种情况?我漏掉了什么?(另外,我不知道还能发布哪些相关信息,请问一下)。请记住,这种情况在重新编译项目时发生(全面重新编译或仅编译已修改的文件),而且在不修改受影响的文件(或使用的类文件)的情况下发生。例如,在完全无关的文件中添加一个简单的printf()语句可能会触发此行为,或者在发生时会使其消失。 我应该把这归咎于-O2吗?因为这种情况完全是随机发生,所以我无法在没有优化标志的情况下重现它。 我正在使用make -j 8,即使清理构建文件夹后也会发生这种情况,但不一定只有在这种情况下才会发生。
make -j 4
)?这种情况是否在执行make clean
后发生过?等等... - Galik