我翻遍了一堆問題,看不到這個,儘管我確定它已經在某個地方了。所以我很抱歉,並認爲這將會結束,但希望有人會首先確認我的答案!C++未定義行爲還是不行? (再次)
我是在想,糾正:
while (--len > -1 && ptr = str[len])
被很好地定義(沒有未定義!)的行爲嗎?我理解的方式是,& &是一個序列點,短路的方式將起作用,這意味着--len > -1
應該首先評估,如果它不安全,則不會發生第二部分。
雖然我不確定自己在這個思維過程中是否正確。
我翻遍了一堆問題,看不到這個,儘管我確定它已經在某個地方了。所以我很抱歉,並認爲這將會結束,但希望有人會首先確認我的答案!C++未定義行爲還是不行? (再次)
我是在想,糾正:
while (--len > -1 && ptr = str[len])
被很好地定義(沒有未定義!)的行爲嗎?我理解的方式是,& &是一個序列點,短路的方式將起作用,這意味着--len > -1
應該首先評估,如果它不安全,則不會發生第二部分。
雖然我不確定自己在這個思維過程中是否正確。
這被定義行爲&&
是一個sequence point和你理解它的方式是正確的。從鏈接的維基百科頁面:
在C [2]和C++,[3]順序點發生在以下位置:
的& &的左邊和右邊的操作數的評價(邏輯之間),|| (邏輯OR)和逗號運算符。例如,在表達式* p ++!= 0 & & * q ++!= 0中,子表達式* p ++!= 0的所有副作用在任何嘗試訪問q之前完成。
但是,這並不確保--len
不會導致索引超出str
的範圍。如果str
是一個空結束的str
你可以改變:
while (--len > -1 && len < strlen(str) && ptr = str[len])
非常感謝:) – 2012-02-28 18:16:23
@hmjd:我會避免在循環的每次運行時重新計算'strlen',它肯定是浪費。如果'len'不如'strlen(str)'開頭,那麼遞減它不應該改變這個事實。當然,這個假設'str'本身不移動,在這裏看起來就是這種情況。 – 2012-02-28 18:16:50
是的,這是正確的。順序爲:
len
遞減len
如果(2)評估以真相比-1
ptr = str[len]
感謝您的快速回答;) – 2012-02-28 19:35:50
您是認爲ptr = str[len]
不執行,如果--len > -1
是假的權利(這可能是一個未定義的行爲是len爲過大的索引數組,我認爲這不是你所害怕的)。如果len事先是INT_MIN,則--len
可能是一個未定義的行爲(如果len被初始化,則不會很有可能),因爲有符號算術的溢出是未定義的行爲。
while (--len > -1 && ptr = str[len])
例如用於LEN = 1
(如果len爲INT)的東西是這樣認爲:
1) len = len-1=0
2) ptr = str[0]
2)是因爲,如果LEN的遞減的if語句的第一部分。 是你想要的嗎?
但是行爲是被定義的,第一部分將被首先檢查。
這實際上是確定的。這裏的關鍵是你不會多次寫入len
。
首先你先遞減len
。然後檢查減量值len
是否至少爲0.接下來,將str[len]
(使用遞減的len
)分配到ptr
。最後檢查ptr
是否爲非空,如果是,則執行while
循環語句。
請注意,如果len
未簽名,則-1
將被提升爲無符號,並且該循環幾乎肯定會使第一次迭代失敗。此外,即使len
如果具有未指定的最小int值(std::numeric_limits<int>::min()
)遞減,也會被簽名。
*這裏的關鍵是你不會多次寫入len。*這不一定是問題。 'map [++ i] = i'只寫入'i'一次,但尚未定義。 – 2012-02-28 18:18:03
取決於此語句之前len的值是多少。如果它是0或更大,該怎麼辦?那麼將評估ptr = str [len]。 – Sid 2012-02-28 17:20:23
是的,好點。這在我的情況下並不危險,但我並沒有首先考慮它是不好的。 :) – 2012-02-28 17:24:06