2016-01-02 81 views
1

編寫這樣的代碼是否安全?自己進行變量初始化

#include <iostream> 

int main() 
{ 
    int x = x-x;// always 0 
    int y = (y)? y/y : --y/y // always 1 
} 

我知道存在未定義的行爲,但不是在這種情況下只是一個垃圾值?如果是這樣,那麼相同的值減去相同的總是0,並且相同的值除以自身(不包括0)總是1.如果不想使用整數字面值,這是一個很大的問題,不是嗎? (佯攻敵人)

+1

如果你討厭字符文字這麼多,你會繼續編寫暴露未定義行爲的代碼(甚至多次在同一語句中),爲什麼不直接使用命名常量呢? – IInspectable

+1

你如何得出結論,你是從自己減去相同的價值?另外,假設一個單位化的值必須是穩定的,'y'最初爲零。在閱讀'/'運算符的RHS之前,爲什麼'-y/y'需要遞減? – hvd

回答

8

請允許我以證明未定義行爲的邪惡魔法:

給出:

#include <iostream> 

int main() 
{ 
    using namespace std; 
    int x = x-x;// always 0 
    int y = (y)? y/y : --y/y; // always 1 

    cout << x << ", " << y << endl; 

    return 0; 
} 

蘋果鐺,編譯-O3

輸出:

1439098744, 0 

undefined是undefined。上述代碼中的評論是謊言這將混淆你的隨機數發生器的未來維護者;-)

+0

作爲分割的結果,y如何變爲0?這超出了我對它的定義。這是魔術。或者將隨機數分開,並在計算結束時將其從1遞減到0? – xinaiz

+4

需要重複多少次...... – LogicStuff

+1

@BlackMoses一個可能的(產生最快和最短的代碼)的解釋是,編譯器指出,經驗調用未定義的行爲,因此它只是刪除整個初始化,不產生機器代碼爲了它。然後,保存變量值的內存(或者甚至是寄存器)恰好碰巧具有這些值。 – hyde

1

未定義的行爲是未定義的。總是。在某些平臺上,東西可能或多或少可靠地工作或破壞,但一般來說,您不能依賴此程序不會崩潰或具有特定值的任何變量。

1

未定義的行爲是未定義的行爲。沒有「在這種情況下不是特定的東西」(除非你實際上正在談論完成編譯的結果,並且查看生成的機器代碼,但不再是C++)。編譯器可以隨心所欲地執行任何操作。

7

我知道存在未定義的行爲,但不是它在這種情況下只是一個垃圾值?如果是,那麼相同的值減去相同的總是0,並且相同的值除以自身(不包括0)始終爲1.

不!不不不!

「垃圾值」是一個「不確定值」。

從本身減去一個不確定的值不會產生零:它會導致您的程序有未定義的行爲[C++14: 8.5/12])。

您不能依賴正常的算術規則來「取消」未定義的行爲。

Your program could travel back in time和破壞權力的遊戲/部隊中喚醒/超人給大家。請不要這樣做!