ISO / IEC 9899(TC2)§6.5 - 2表达式告诉我们:
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该是只读的,以确定要存储的值。
这是我记住的,记住的,并会告诉任何人问我为什么标题中的行会产生意想不到的输出。
但今天我刚刚发现了这一行:
§7.19.6 - 1格式化输入/输出功能:
格式化的输入/输出函数的行为应该与每个说明符关联的操作之后有一个序列点。
这让我想到了:
虽然
int i = 0;
printf ("%d, %d", ++i, i++);
应该是未定义的,下一个例子应该是所提到的条款:
int i = 0;
printf ("%d, %d, %d", ++i, i, i++);
但输出是:
2, 2, 0
我从来没有见过更好的例子,表明未定义的行为。
但为什么呢? 如果该条款为真
“[...]表现得就像在与每个说明符相关联的操作之后存在一个序列点。”
然后将§6.5 - 2下的规则应用到与说明符关联的每个actiosn上,不允许我们跨越该规则,如下所示:
(SP表示相关序列点)
SP 1 ++i
SP 2 i
SP 3 i++
从上一个和下一个SP之间给定范围内的SP1,++i
是i
存储值的唯一修改。
从SP2开始,上一个和下一个SP之间的范围是++i
和i
,其中++i
仍然是该值的唯一修改。
如果我们现在采用SP3,那么之前的SP(SP2)和下一个SP(调用结束)之间的所有事情都是:
i
和i++
仍然只是对前一个和下一个SP之间整个范围内的i
进行了一次修改。
那么我在这里解释序列点的工作方式是错误的吗?
答案 0 :(得分:2)
问题不在于与说明符相关的操作。问题在于计算./dir1/file1:step_2:
函数的参数,该函数在第一个说明符执行任何操作之前完成。
./dir1/file2:step_2:
想象一下,如果代码是:
printf
这里很清楚。包装器不会改变任何东西。