首先我們來看一段代碼:
int a() { return std::puts("a"); }
int b() { return std::puts("b"); }
int c() { return std::puts("c"); }
void z(int, int, int) {}
int main() {
z(a(), b(), c()); // 允許全部 6 種輸出排列
return a() + b() + c(); // 允許全部 6 種輸出排列
}
這段代碼是cppreference網站中對與表達式求值順序,做的一個引入介紹。這個代碼中說的就是對於表達式求值順序規則:若某個函數調用既不按順序早於又不按順序晚於另一函數調用,則它們是順序不確定。
這段代碼的輸出結果可能為:
a
b
c
a
b
c
//或者
b
a
c
a
c
b
//其實順序完全不確定,進行排列組合會有多種輸出順序。
平時求值順序不確定的情況,主要有以下四種:
1、若某個函數調用既不按順序早於又不按順序晚於另一函數調用,則它們是順序不確定的
2、對分配函數(operator new)的調用相對於 new 表達式中構造函數參數的求值來說,是順序不確定的(c++17后先構造后分配)
3、函數調用表達式中,每個形參的初始化的值計算和副作用相對於任何其他形參的初始化的值計算和副作用是順序不確定的。
4、帶括號的初始化器中的逗號分隔的表達式列表中的每個表達式,如同函數調用一般求值(順序不確定)。