編寫這樣的代碼是否安全?自己進行變量初始化
#include <iostream>
int main()
{
int x = x-x;// always 0
int y = (y)? y/y : --y/y // always 1
}
我知道存在未定義的行爲,但不是在這種情況下只是一個垃圾值?如果是這樣,那麼相同的值減去相同的總是0,並且相同的值除以自身(不包括0)總是1.如果不想使用整數字面值,這是一個很大的問題,不是嗎? (佯攻敵人)
編寫這樣的代碼是否安全?自己進行變量初始化
#include <iostream>
int main()
{
int x = x-x;// always 0
int y = (y)? y/y : --y/y // always 1
}
我知道存在未定義的行爲,但不是在這種情況下只是一個垃圾值?如果是這樣,那麼相同的值減去相同的總是0,並且相同的值除以自身(不包括0)總是1.如果不想使用整數字面值,這是一個很大的問題,不是嗎? (佯攻敵人)
請允許我以證明未定義行爲的邪惡魔法:
給出:
#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。上述代碼中的評論是謊言這將混淆你的隨機數發生器的未來維護者;-)
作爲分割的結果,y如何變爲0?這超出了我對它的定義。這是魔術。或者將隨機數分開,並在計算結束時將其從1遞減到0? – xinaiz
需要重複多少次...... – LogicStuff
@BlackMoses一個可能的(產生最快和最短的代碼)的解釋是,編譯器指出,經驗調用未定義的行爲,因此它只是刪除整個初始化,不產生機器代碼爲了它。然後,保存變量值的內存(或者甚至是寄存器)恰好碰巧具有這些值。 – hyde
未定義的行爲是未定義的。總是。在某些平臺上,東西可能或多或少可靠地工作或破壞,但一般來說,您不能依賴此程序不會崩潰或具有特定值的任何變量。
未定義的行爲是未定義的行爲。沒有「在這種情況下不是特定的東西」(除非你實際上正在談論完成編譯的結果,並且查看生成的機器代碼,但不再是C++)。編譯器可以隨心所欲地執行任何操作。
我知道存在未定義的行爲,但不是它在這種情況下只是一個垃圾值?如果是,那麼相同的值減去相同的總是0,並且相同的值除以自身(不包括0)始終爲1.
不!不不不!
「垃圾值」是一個「不確定值」。
從本身減去一個不確定的值不會產生零:它會導致您的程序有未定義的行爲([C++14: 8.5/12]
)。
您不能依賴正常的算術規則來「取消」未定義的行爲。
Your program could travel back in time和破壞權力的遊戲/部隊中喚醒/超人給大家。請不要這樣做!
如果你討厭字符文字這麼多,你會繼續編寫暴露未定義行爲的代碼(甚至多次在同一語句中),爲什麼不直接使用命名常量呢? – IInspectable
你如何得出結論,你是從自己減去相同的價值?另外,假設一個單位化的值必須是穩定的,'y'最初爲零。在閱讀'/'運算符的RHS之前,爲什麼'-y/y'需要遞減? – hvd