首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 前置遞增運算符鏈式調用的求值順序陷阱:為什麼 (++a).getx() 與 (++a).gety() 輸出 7 6?

     編輯:程式設計疑難解答

代碼現場

class Point {
    int x, y;
    Point& operator++() { ++x; ++y; return *this; }
    int getx() { return x; }
    int gety() { return y; }
};

Point a(5,5);
cout << (++a).getx() << " " << (++a).gety() << endl; // 輸出 7 6

標準規定

C++ 標準(C++17 前)未規定函數參數的求值順序。編譯器可自由選擇先計算左參數還是右參數。

MSVC 行為(從右向左)

  1. 先計算右參數 (++a).gety():
    • ++a → x=6, y=6,返回引用。
    • .gety() → 返回 6。
  2. 再計算左參數 (++a).getx():
    • ++a → x=7, y=7。
    • .getx() → 返回 7。
  3. 輸出 7 6。

GCC/Clang 行為(通常從左向右)

可能輸出 6 7。跨編譯器不可移植。

避免方法

// 拆分語句,明確順序
++a;
int x = a.getx();
++a;
int y = a.gety();
cout << x << " " << y; // 穩定輸出 6 7

C++17 改進

C++17 規定運算符調用的求值順序:左操作數先於右操作數。但函數參數順序仍未規定。升級編譯器並開啟 -std=c++17 可獲得更可預期行為,但最好仍避免依賴求值順序的代碼。

參考資料

博客深度分析:C++ 求值順序詳解

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved