c - 有人可以解释如何评估这个 C 代码片段 wrt 序列点吗?
问题描述
这是 C 下的未定义行为吗?我这样说是因为我认为该函数inc(int *k)
可以被认为是一个表达式,其副作用是更新k
. 那么,这是否等同于i=i++
UB?
#include <stdio.h>
/*Edited(See comments below on dbush's answer)*/
int inc(int *k) {return ++(*k);}
/*End of edit*/
int main()
{
int i=0;
int *ptr = &i;
i = inc(ptr);
printf("%d\n", i);
}
解决方案
该行为定义良好,因为调用函数算作一个序列点,并且函数中的每个语句也是一个序列点。这与将函数的主体放在它的位置上是不一样的。
首先inc
被称为。这会调用一个序列点。
在函数中,return ++(*k)
执行语句,首先计算包含表达式。这导致递增到 1,表达式计算为 的新值,即 1。语句从函数返回该值,并且该语句i
的完成是另一个序列点,因此递增的副作用是保证完整。main
i
return
i
再回来,从返回main
的值 1inc
然后分配给i
。
如果你这样做了:
i = ++(*ptr);
那将是未定义的行为,因为在分配 to 和递增viai
的副作用之间没有序列点。i
*ptr
推荐阅读
- python - 正则表达式返回匹配加上字符串直到下一个匹配
- javascript - 如何将表的列名存储在雪花的数组中
- python - ValueError: Value tf.Tensor.. shape=(), dtype=float64) has enough rank for batching.?
- c - setenv 和 unsetenv 如何改变堆栈?
- c# - 'Identity.UserManager`1[ProjectName.ApplicationUser]' 类型的服务没有注册。当容器被销毁时可用)'
- sql - 将 Firebase 实时数据库数据保存到 SQL 表或 NoSQL 表中
- r - 如何使用 IntelliJ IDEA for R 代码解决退出代码 3
- postgresql - Robot Framework - 使用 PostgreSQL 从数据库中执行 Sql 脚本关键字
- python - 用 bs4 抓取 Google 知识框
- aws-lambda - 如何使用 SAM deploy 获取 lambda,以及 AutoPublishAlias 和其他别名