是 i=f();当 f 修改 i 时定义?

发布于 2024-11-07 20:58:49 字数 528 浏览 0 评论 0原文

相关问题: 赋值运算符不存在的任何充分理由序列点?

comp.lang.c FAQ 我会推断下面的程序是未定义的。奇怪的是,它只提到对 f 的调用作为参数计算和控制权转移到 f 之间的序列点。从 f 到调用表达式的控制转移未列为序列点。

int f(void) { i++; return 42; }
i = f();

真的是未定义吗?

作为我在许多问题中添加的尾注,我对静态分析的背景感兴趣。我不是自己写这个,我只是想知道我是否应该在其他人编写的程序中发出警告。

Related question: Any good reason why assignment operator isn't a sequence point?

From the comp.lang.c FAQ I would infer that the program below is undefined. Strangely, it only mentions the call to f as a sequence point, between the computation of the arguments and the transfer of control to f. The transfer of control from f back to the calling expression is not listed as a sequence point.

int f(void) { i++; return 42; }
i = f();

Is it really undefined?

As an end-note that I add to many of my questions, I am interested in this in the context of static analysis. I am not writing this myself, I just want to know if I should warn about it in programs written by others.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七堇年 2024-11-14 20:58:49

控制权从 f 转移回
未列出调用表达式
作为序列点。

是的。

完整表达式的评估结束时

 

构成一个完整的表达式
表达式语句,或其中之一
控制 if 的表达式,
switch、while、for 或 do/while
语句或表达式
初始化器或返回语句

你有一个 return 语句,因此,你有一个序列点。

它甚至没有出现

int f(void) { return i++; } // sequence point here, so I guess we're good
i = f();

未定义的情况。 (这对我来说有点奇怪。)

The transfer of control from f back to
the calling expression is not listed
as a sequence point.

Yes it is.

at the end of the evaluation of a full expression

 

The complete expression that forms an
expression statement, or one of the
controlling expressions of an if,
switch, while, for, or do/while
statement, or the expression in an
initializer or a return statement.

You have a return statement, therefore, you have a sequence point.

It doesn't even appear that

int f(void) { return i++; } // sequence point here, so I guess we're good
i = f();

is undefined. (Which to me is kind of weird.)

一生独一 2024-11-14 20:58:49

这根本不是未定义的。 C99 附录 C 中列出的序列点之一是完整表达式的结尾,其中一个是 return 语句中的表达式。

由于您返回 42,因此紧跟在 return 语句之后有一个序列点。

为了完整起见,这里列出了 C99 序列点,相关的序列点以粗体显示:

以下是 5.1.2.3 中描述的序列点:


  • 在计算参数之后调用函数 (6.5.2.2)。
  • 以下运算符的第一个操作数结束:逻辑 AND && (6.5.13);逻辑或|| (6.5.14);有条件的? (6.5.15);逗号 , (6.5.17)。
  • 完整声明符的结尾:声明符 (6.7.5);
  • 完整表达式的结尾:初始化器 (6.7.8);表达式语句中的表达式 (6.8.3);选择语句的控制表达式(if 或 switch)(6.8.4); while 或 do 语句的控制表达式 (6.8.5); for 语句的每个表达式 (6.8.5.3); 返回语句中的表达式 (6.8.6.4)
  • 紧接着库函数返回之前 (7.1.4)。
  • 与每个格式化输入/输出函数转换相关的操作之后
    说明符(7.19.6、7.24.2)。
  • 每次调用比较函数之前和之后,以及
    也在对比较函数的任何调用和对象的任何移动之间
    作为参数传递给该调用 (7.20.5)。

That's not undefined at all. One of the sequence points listed in Appendix C of C99 is the end of a full expression, of which one is the expression in a return statement.

Since you're returning 42, there's a sequence point immediately following that return statement.

For completeness, the C99 sequence points are listed here, with the relevant one bolded:

The following are the sequence points described in 5.1.2.3:


  • The call to a function, after the arguments have been evaluated (6.5.2.2).
  • The end of the first operand of the following operators: logical AND && (6.5.13); logical OR || (6.5.14); conditional ? (6.5.15); comma , (6.5.17).
  • The end of a full declarator: declarators (6.7.5);
  • The end of a full expression: an initializer (6.7.8); the expression in an expression statement (6.8.3); the controlling expression of a selection statement (if or switch) (6.8.4); the controlling expression of a while or do statement (6.8.5); each of the expressions of a for statement (6.8.5.3); the expression in a return statement (6.8.6.4).
  • Immediately before a library function returns (7.1.4).
  • After the actions associated with each formatted input/output function conversion
    specifier (7.19.6, 7.24.2).
  • Immediately before and immediately after each call to a comparison function, and
    also between any call to a comparison function and any movement of the objects
    passed as arguments to that call (7.20.5).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文