C 左值和函数结果——依赖关系?
考虑以下代码段:C 左值和函数结果——依赖关系?,c,types,lvalue,C,Types,Lvalue,考虑以下代码段: int func(char *ptr); ... n += func(p + n); 由于函数的参数依赖于左值,此代码是否产生未定义的行为?我假设编译器将计算函数的结果,然后递增p+n,或者这可能是特定于编译器的?在函数进入函数调用之前有一个序列点。这意味着与参数相关的每个值计算和副作用都是在函数调用中输入函数之前完成的 n += func(p + n); C11-§6.5.2.2/10: 在函数指示符和实际参数的求值之后但在实际调用之前有一个序列点 那么,万一 n +=
int func(char *ptr);
...
n += func(p + n);
由于函数的参数依赖于左值,此代码是否产生未定义的行为?我假设编译器将计算函数的结果,然后递增
p+n
,或者这可能是特定于编译器的?在函数进入函数调用之前有一个序列点。这意味着与参数相关的每个值计算和副作用都是在函数调用中输入函数之前完成的
n += func(p + n);
C11-§6.5.2.2/10:
在函数指示符和实际参数的求值之后但在实际调用之前有一个序列点
那么,万一
n += func(p + n);
p+n
将在函数调用之前计算 函数进入函数调用之前有一个序列点。这意味着与参数相关的每个值计算和副作用都是在函数调用中输入函数之前完成的
n += func(p + n);
C11-§6.5.2.2/10:
在函数指示符和实际参数的求值之后但在实际调用之前有一个序列点
那么,万一
n += func(p + n);
p+n
将在函数调用之前计算
n += func(p + n);
定义良好,因为只有在函数调用完成后才能访问n
进行写入。只有在读取n
的值后才能完成函数调用
定义良好,因为只有在函数调用完成后才能访问
n
进行写入。只有在读取n
@EugeneSh.的值后才能完成函数调用。@EugeneSh:添加引用,这就是答案。@EugeneSh:添加引用,这就是答案。似乎“参数的所有副作用在输入函数之前都已完成”的语句具有误导性。它在这里如何应用?这里的副作用是什么?n的增量
?但这并不是在电话之前发生的p+n
使用先前的值n
@EugeneSh进行评估。;实际上,这个问题似乎缺少一些信息。在这种情况下,p+n
的值计算。OP说:我假设编译器将计算函数的结果,然后递增p+n
。但事实恰恰相反p+n
将首先计算,然后函数将返回其结果。@EugeneSh。;不。标准说:表达式a和B的计算之间存在一个序列点,这意味着与a相关的每个值计算和副作用都是在与B相关的每个值计算和副作用之前排序的。这不仅与副作用有关,还与abot值计算有关。在本例中,我讨论的是p+n
的值计算,因为参数没有副作用,所以我认为它实际上与序列点没有什么关系。这只是一个常规的读取-计算-存储计算。@EugeneSh。;对没什么好担心的。我认为OP只是想得太多了。似乎“参数的所有副作用都在函数输入之前完成”的说法是误导性的。它在这里如何应用?这里的副作用是什么?n的增量
?但这并不是在电话之前发生的p+n
使用先前的值n
@EugeneSh进行评估。;实际上,这个问题似乎缺少一些信息。在这种情况下,p+n
的值计算。OP说:我假设编译器将计算函数的结果,然后递增p+n
。但事实恰恰相反p+n
将首先计算,然后函数将返回其结果。@EugeneSh。;不。标准说:表达式a和B的计算之间存在一个序列点,这意味着与a相关的每个值计算和副作用都是在与B相关的每个值计算和副作用之前排序的。这不仅与副作用有关,还与abot值计算有关。在本例中,我讨论的是p+n
的值计算,因为参数没有副作用,所以我认为它实际上与序列点没有什么关系。这只是一个常规的读取-计算-存储计算。@EugeneSh。;对没什么好担心的。我认为OP只是想得太多了。如果序列点在这里是相关的,那么如何用序列点来解释呢?看起来他们不是。这里没有副作用。@EugeneSh.,即使函数调用涉及一个序列点,它只适用于参数的求值,我认为它与决定n+=func(p+n)无关代码>定义得很好。如果序列点与此处相关,如何用序列点来解释?看起来他们不是。这里没有副作用。@EugeneSh.,即使函数调用涉及一个序列点,它只适用于参数的求值,我认为它与决定n+=func(p+n)无关代码>定义良好。