有問題的C 程式碼,由Bjarne Stroustrup 在《C 程式語言》第四版中提供C 程式語言」使用函數鏈來修改字串:
<code class="cpp">void f2() { std::string s = "but I have heard it works even if you don't believe in it"; s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, ""); assert(s == "I have heard it works only if you believe in it"); }</code>
此程式碼演示如何連結update() 操作來更改字串s。 >
雖然程式碼看起來很簡單,但它涉及未指定的順序求值,特別是對於涉及函數呼叫的子表達式 雖然它不會呼叫未定義的行為(因為所有副作用都發生在函數呼叫內),但它確實表現出未指定的行為。 ) 沒有明確定義。值順序:我們可以看到以下子表達式是不確定排序的(由括號中的數字表示):
s.replace(0, 4 , "") (1)s.find("偶數") (2)s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
s.replace(s.find("偶數"), 4, "僅") ( 3)
需要注意的是,此程式碼不呼叫未定義的行為。未定義的行為通常涉及存取未初始化的變數或嘗試存取其邊界之外的記憶體。在這種情況下,所有副作用都發生在函數呼叫內,且程式碼不會存取無效的記憶體位置。
但是,程式碼確實表現出未指定的行為,這表示C 標準沒有定義子運算式的求值。這可能會導致不同的編譯器產生不同的結果,甚至是同一程式的不同運行。
C 標準委員會已認識到此問題並提出更改以細化表達式求值順序慣用語C .對C 20 中的[expr.call]p5 的建議更改指定“後綴表達式在表達式清單中的每個表達式和任何預設參數之前排序”,這將消除此程式碼中未指定的行為。
以上是「C 程式語言」中的函數鍊是否表現出未指定的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!