- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是一个示例片段:
int i = 4,b;
b = foo(i++) + foo(i++);
我很确定它不是未定义,因为在调用foo
之前有一个序列点。但是,如果我使用 -Wall
标志编译代码,则会生成编译器警告,提示 warning: operation on 'i' may be undefined
。我意识到它说的是 may
,但我只是想仔细检查一下我是否正确。
最佳答案
行为未定义。
b = foo(i++) + foo(i++);
如您所说,在第一个 i++
的求值和对 foo
的调用之间有一个序列点,同样在第二个 i++ 的求值之间
和调用 foo
。但是在 i++
的两个求值之间,或者更具体地说,在它们的副作用(修改 i
)之间没有(必然)序列点。
引用N1570 2011 ISO C 标准草案,第 6.5.2.2p10 节:
There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.
第二句在这里意义重大:i++
的两次求值都是“indeterminatelysequenced"相对于两个函数调用,这意味着它们可以在调用 foo
之前或之后发生。(不过,它们不是 unsequenced;它们中的每一个在调用之前或之后发生,但未指定是哪一个。)
6.5p2 说:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.
将它们放在一起,符合规范的实现可以按以下顺序评估表达式:
i++
并将值保存在某处。i++
并将值保存在某处。foo
,将第一个保存的值作为参数传递。foo
,将第二个保存的值作为参数传递。b
中。步骤 1 和步骤 2 之间没有序列点,都修改了 i
,因此行为未定义。
(这实际上有点过分简化了;修改 i
的副作用可以从 i++
的结果确定中分离出来。
底线:我们知道
b = i++ + i++;
具有未定义的行为,原因已被反复解释。在函数调用中包装 i++
子表达式确实添加了一些序列点,但这些序列点不会将 i++
的两个评估分开,因此不会导致行为变为定义明确。
底线:请不要写那样的代码。即使行为得到了很好的定义,证明它并确定行为应该是什么也比值得更困难。
关于c - foo(i++) + foo(i++) 在 ANSI C 中未定义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21031480/
public class Foo : IFoo ... 和有什么区别 IFoo foo = new Foo(); 和 Foo foo = new Foo(); 最佳答案 区别仅在于变量的声明类型。每当
class Foo { public: explicit Foo() {} explicit Foo(Foo&) {} }; Foo d = Foo(); error: no matc
是 foo as? Foo完全等同于 foo as Foo? ? 如果是,那为什么两者都有? 如果不是,那么有什么区别? 最佳答案 as?是 safe cast operator . 通常,如果您尝试
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
这个问题在这里已经有了答案: Why is there an injected class name? (1 个回答) 关闭5年前。 一位同事不小心写了这样的代码: struct foo { fo
我遇到了这些关键字::foo、::foo、::bar/foo 和 :bar/foo 您能举例说明差异吗? 最佳答案 :foo 是一个非完全限定的关键字。它没有关联的命名空间。 (name :foo)
有人问我如何简化这个 lambda (Foo foo) -> foo.getName() 还有更好的写法吗? 最佳答案 Foo::getName。 假设getName是一个实例方法,其签名中的参数列表
编写此规则集的 CSS 组合器或简写是什么? foo bar, foo biz, foo gaz > boo, foo tar { ... } 我很确定我在 MDN 的某处读到过有一个。是不是: f
我有一个用这个字符串填充的输入文本 "foo foo"但插入后字符串看起来像这样 "foo foo" .我该如何解决?我想以第一种格式显示字符串! 最佳答案 你可能有这样的事情: " /> 更改 va
假设我有一个不可复制类Foo,它的构造函数之一恰好接收到对 Foo 的引用。 class Foo { public: Foo(Foo& parent) {...} private: v
class Artist @@song_count = [] attr_accessor :name, :songs def initialize(name) @name = name
请解释为什么这些 Perl 函数的调用方式在函数定义之上决定了它们是否运行。 print "Why does this bare call to foo not run?\n"; foo; print
文件名分为三种类型 首先( Root 于某种“当前工作目录”之下) ../foo ./foo bar/foo # really in this group? 和( Root 于绝对路径,独立于 CWD
我想自动连接 foo: @Autowired Foo foo 但我无法修改类 Foo 并将其标记为 @Component。 Autowiring foo 最干净的方法是什么? 顺便说一句,如果您需要使
我一直在使用 Python 的 ElementTree 创建 XML 文档,到目前为止一切顺利。然而我现在面临的问题是,由于项目要求,我需要生成一个 XML 文档,其中包含带有开始和结束标签的元素以及
class Foo { public: Foo(){} private: Foo(const Foo &); }; Foo f(); Foo f1 = Foo(); 我发现当我将 Fo
我有一个 jquery 对话框,上面有一个按钮(我的按钮,不是对话框按钮之一)。 设置对话框后,我有以下代码: $('#bar').click(foo('baz')); 当我加载页面并显示对话框时,f
我遇到了以下变量的情况: var foo: Foo | Foo | Foo; 动态生成(使用 keyof 和 stuff),这在代码的那个点是完全有意的。但是,我需要调用像这样定义的对象内部的方法:
clang 3.5.0 和 gcc 4.9.1 从代码生成的可执行文件 #include struct Foo { Foo() { std::cout << "Foo()" << std::e
对于声明为 Foo& foo = ...; 的 foo,lambdas 的按值捕获和按引用捕获语义之间有什么区别吗? 最佳答案 我认为你已经陷入了一个常见的误解......引用是对真实对象的别名。初始
我是一名优秀的程序员,十分优秀!