回答
通過要求:
一般來說,東西都需要一個理由來是序列點。他們不需要原因而不是是一個序列點;這是默認設置。
例如,由於短路行爲,&&
必須是序列點:如果左側爲假,則不應評估右側。 (這不僅僅是優化,右邊可能有副作用,和/或取決於左邊是真實的,如ptr && ptr->data
。)因此,左側必須首先評估,右側另一方面,爲了看看是否應該評估右側。
=
這個理由不存在,因爲雖然對雙方都有「評估」(儘管雙方都有不同的限制:左邊必須是左值 - l
不代表「左」,順便說一句;代表「位置」,如在內存中的位置 - 我們不能分配給臨時或文字),先評估哪一方並不重要 - 只要長因爲雙方在實際任務之前進行評估。
它是(有點)。運算符=(可以由工程師定義(也就是用戶定義的運算符=用於類類型))只是函數調用的語法糖。因此它具有與函數調用相同的「序列點」語義。
如果我們正在考慮內置類型,那麼我認爲這是一件好事。
您不想引入過多的順序點,因爲這會妨礙優化。
有很多理由不要求任何一方先評估另一方。一個更有趣的問題是,在賦值運算符本身做什麼之前,是否應該要求對雙方進行評估,並且有副作用。我會建議這樣的要求會緩解一些別名限制,但在某些情況下需要更多的編譯器工作。例如,假設「foo」和「bar」是指向地址重疊的大型結構的指針。聲明「* foo = * bar」將代表當前標準下未定義的行爲。如果在操作數評估和任務之間有一個序列點,那麼這樣的陳述將被保證「有效」。對於賦值運算符來說,這種保證要求更復雜,即使實際上指針永遠不會重疊,也需要更大更慢的代碼。
例子:
unsigned char foo[100]; typedef struct {int x, int y;} POINT; POINT *p1 = (POINT*)foo; POINT *p2 = (POINT*)(&(p1->y));
鑑於上述聲明,我認爲下面的語句具有嚴格定義的行爲表明不涉及任何未定義行爲。
p1->y = somevalue; // Sets p2->x to somevalue p2->x = somevalue; // Sets p1->y to somevalue *p1 = mystruct; // Sets p2->x to mystruct.y *p2 = mystruct; // Sets p1->x to mystruct.x
下面的兩個語句,然而,會涉及未定義行爲:
*p1 = *p2; *p2 = *p1;
如果有在平等的順序點標誌,編譯器將不得不採取比較p1和p2,要不然將源操作數複製到臨時位置,然後將其複製到目標位置。但是,該標準清楚地表明,上述兩個聲明都被認爲是未定義的行爲。該標準要求編譯器生成在將結構複製到非重疊結構時能夠正確工作的代碼,但對結構重疊時編譯器可能執行的操作沒有限制。一個編譯器,將處理器變成循環發送「Frink規則!」每個打開的TCP套接字都不會違反標準。
- 1. 什麼是| =賦值運算符?
- 2. 爲什麼賦值運算符返回ref不是指針?
- 3. 什麼是PHP不同的賦值運算符,它們有什麼不同
- 4. 爲什麼在VB.NET中賦值運算符不可重載?
- 5. 爲什麼複製構造函數和賦值運算符是不允許的?
- 6. 理解的CComBSTR賦值運算符
- 7. 爲什麼賦值運算符返回一個值而不是引用?
- 8. 什麼是返回類型的賦值運算符?
- 9. 賦值運算符不總是叫
- 10. 爲什麼C++將賦值(=)視爲重載運算符?
- 11. BigDecimal的賦值運算符
- 12. 爲什麼Javascript運算符「&&」很奇怪?
- 13. 與賦值運算符一起使用的邏輯非(!)運算符是否總是將賦值運算符左側的變量賦值爲false?
- 14. 爲什麼對於短基元,有賦值運算符(&=,+ =)但沒有非賦值運算符(&,+)?
- 15. java複合賦值運算符和賦值運算符
- 16. 移動賦值運算符VS拷貝賦值運算符
- 17. ActionScript賦值運算符,>>>是什麼意思?
- 18. 運算符超載賦值運算符
- 19. 什麼是切換到jQuery 1.4的一些很好的理由
- 20. 使用SQL視圖的一個很好的理由是什麼?
- 21. 清除std :: vector需要賦值運算符。爲什麼?
- 22. 爲什麼Ada中沒有(增強賦值)運算符,如+ =, - =或++?
- 23. 爲什麼調用賦值運算符觸發銷燬函數?
- 24. 爲什麼被用來代替賦值運算符
- 25. 爲什麼C沒有邏輯賦值運算符?
- 26. Visual C++ 2012:爲什麼priority_queue需要重載賦值運算符?
- 27. 爲什麼remove_if(...,lambda)表達式需要賦值運算符?
- 28. 爲什麼擴展方法類不能嵌套是否有很好的理由?
- 29. 理解賦值運算符 - javascript
- 30. 爲什麼`std :: string`的賦值運算符是按值而不是`const`引用`char`的?
這需要編譯器在RHS之前計算LHS。你爲什麼要創造這種限制? – 2010-12-06 01:32:18
`a = b = c = 0;` – pmg 2010-12-06 01:34:18
一般而言,事物需要一個理由來** **一個序列點。他們不需要一個理由**而不是一個序列點;這是默認設置。 – 2010-12-06 01:59:22