c - 诸如 "sequence-point"或 "int a=4,*ptr=&a;"之类的语句是否存在 "x+=4,y=x*2;"问题?

标签 c sequence-points

我对整个序列点的理解是基本的。我所拥有的只是一些粗略的直觉想法,即“一旦遇到一个序列点,我们就可以确定之前评估的所有副作用都是完整的”。我还读到,在像 printf("%d",a++,++a,a++) 这样的语句中,行为是未定义的,因为逗号并不表示序列点,而分号表示。因此,与其凭直觉进行猜测和判断,我觉得对此有一个非常严谨和确凿的答案会对我有很大帮助。

在 C 语言中,以下类型的语句是否安全且确定:

int a=4,*ptr=&a;  //Statement 1

x+=4,y=x*2;  //Statement 2  (Assume x and y are integer variables)

如果是,怎么办?特别是在第二种情况下,如果逗号不是序列点,我们如何在赋值 中使用它之前确定 x 已经递增了 4 y=x*2?对于第一条语句,在将其地址分配给 ptr 之前,我如何确定 a 已被初始化并分配内存?我应该谨慎行事并使用以下内容吗?

int a=4,*ptr;
ptr=&a;

x+=4;
y=x*2;

编辑 我对逗号运算符的理解告诉我这些语句是安全的。但是在阅读了序列点以及诸如 printf("%d",a++,++a,a++) 之类的东西是如何未定义之后,我又重新考虑了。

最佳答案

在函数调用中分隔函数参数的逗号不是逗号运算符 - 它只是标点符号,恰好与逗号运算符的拼写方式相同。不同函数参数的计算之间没有顺序点,所以这就是为什么在这种情况下你会得到 UB。

另一方面,在你的表达中:

x+=4,y=x*2;

这里的逗号一个逗号运算符,引入了一个序列点;没有 UB。

在声明中,声明符之间的逗号也不是逗号运算符;但是,完整声明符(一个声明符不是另一个声明符的一部分)的末尾确实引入了一个序列点,因此声明如下:

int a = 2, b = a + 1;

不是 UB。

关于c - 诸如 "sequence-point"或 "int a=4,*ptr=&a;"之类的语句是否存在 "x+=4,y=x*2;"问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16262983/

相关文章:

c - 这个程序有任何序列点问题吗?

c++ - C和C++中带有序列点和UB的差异

c - 在地址中使用先前参数时 Sscanf 未初始化的值

连接被拒绝 TCP 套接字

c - 如何打印 char * a[] 的返回值?

C结构对齐和网络协议(protocol)头

C - fscanf,格式问题

c++ - 标准 C++11 是否保证在函数调用之前创建传递给函数的临时对象?

c - 为什么这些构造使用增量前和增量后未定义的行为?

打印同名 C 文件源代码的 C 程序