我有一個奇怪的問題有時與GCC(4.6.4,Ubuntu 12.04),我用它來編譯一個巨大的項目(數百個文件和數十萬行代碼),但我最近發現了一些東西。經過一定的編譯(似乎是隨機發生的),我得到不同,錯誤地編了一段特定的代碼,在我的代碼導致未定義的行爲:兩個GCC編譯相同的輸入,生成兩個不同的代碼(第二個錯誤)
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
的制定者似乎得到內聯很可能因爲編譯標誌-02,:
-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?如果沒有優化標記,我無法重現它,因爲這完全是隨機的。 我使用使-j 8,這種情況即使在清潔生成文件夾,但不一定這樣做
你可能有一個附近的未定義的行爲。 – kiwixz
這聽起來像你違反了一個定義規則,但我不能告訴你如何,或者以什麼具體方式導致你的問題。 –
太難猜測了。我們可能需要一個[MCVE](http://stackoverflow.com/help/mcve) – AndyG