論無解的阿里2016校園招聘題

以下代碼是阿里2016級校園招聘比試題目:
//clang提示編譯警告:multiple unsequenced modifications to v
#include <iostream>
using namespace std;


void __cdecl func(const int& v1, const int&v2){
         cout<<v1<<' '<<v2<<endl;



int main(){
        int v = 0;
        func(++v, v++);



然後有四個答案,其中有2 0和2 1,事實上,在微軟的Visual Studio上測試結果是2 0,在Clang和XCode(後臺使用Clang)上是2 1,那麼問題來了,哪個對?


結果是沒有一個對,也沒有一個錯,這個題目是沒有答案的。
C(++)語言中有序列點的概念,序列點要求在序列點上,前面求值的所有副作用應該全部完成,比如,函數調用就是一個序列點,在函數調用實施前,參數的求值及其副作用應該被全部計算完成。C語言中規定,逗號運算符、三元運算符、邏輯與、邏輯或有序列點。


逗號運算符:(函數調用裏面的那個逗號是參數分割號,而不是逗號運算符)
#include <Iostream>
using namespace std;


void f(const int& ref){
        cout<<ref<<' ';
}  


int main(){
    int val = 0;
    f(val++),f(val++);
}
以上代碼顯然輸出0,1。因爲逗號運算符是個序列點,左邊的f調用及其副作用必須先計算再進行右邊的f調用及副作用。




三元運算符,邏輯與,邏輯或等與此類似,不再詳細描述。


在最開始的代碼裏面,惟一可以保證的是在func調用之前,兩個參數v1,和v2均會被計算、副作用均已完成以及參數從右到左入stack,至於先計算v++還是++v及其副作用是無定義的,也就是說,編譯器想怎麼計算就怎麼計算,保不準在某個編譯器上輸出1,1。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章