2013-08-29 44 views
7

這是又一個序列點的問題,而是一個相當簡單的一個:函數調用的順序點?

#include <stdio.h> 
void f(int p, int) { 
    printf("p: %d\n", p); 
} 

int g(int* p) { 
    *p = 42; 
    return 0; 
} 

int main() { 
    int p = 0; 
    f(p, g(&p)); 
    return 0; 
} 

這是不確定的行爲?或者撥打g(&p)作爲順序點?

回答

9

不,它不調用undefined行爲。它只是未指定,因爲評估函數參數的順序未在標準中指定。因此,根據編譯器決定的評估順序,輸出可能爲042

+6

問題還問'g(&p)'是否充當序列點。在評價g(&p)時有兩個順序點:在評價'g'和評價'&p'之間,評價'完整表達式''* p = 42;'和'return'中的'0'。但他們都沒有排序評價'g(&p)'的參數'p'的評價。 –

+0

@EricPostpischil:很棒的評論。 :-) – Nawaz

4

程序的行爲是不確定的,因爲我們不知道的函數參數的計算順序,從draft C++ standard1.9程序執行第3款

某些其它方面和操作的抽象機在本國際標準中被描述爲未指定的(例如,對函數的參數進行評估的順序)。本標準儘可能定義了一系列允許的行爲。 [...]

並進入之前的功能,從部分5.2.2函數調用第8段從參數所有副作用測序:

[注:後綴的評價表達式和參數表達式都是相互不相關的。 在輸入函數之前,參數表達式評估的所有副作用都被排序(參見1.9)。末端注]

至於C兩個點都覆蓋在C99 draft standard在第6.5.2.2函數調用第10段

功能標誌的評估順序,實際的參數,並 實際參數內的子表達式未指定,但在實際調用之前有一個序列點 。因此,在這兩個C

C++您可與f(0,0)f(42,0)結束。