2013-08-29 39 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)结束。