问题标签 [sequence-points]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - std::initializer_list 和元素的求值顺序
逗号 ( ,
) 是 中的序列点std::initializer_list
吗?
示例:这是不是 UB:
c++ - 为什么 a = (a+b) - (b=a) 是交换两个整数的错误选择?
我偶然发现了这段代码,用于在不使用临时变量或使用位运算符的情况下交换两个整数。
但我认为此代码在交换语句中具有未定义的行为,a = (a+b) - (b=a);
因为它不包含任何序列点来确定评估顺序。
我的问题是:这是交换两个整数的可接受解决方案吗?
c - ANSI C 中未定义 foo(i++) + foo(i++) 吗?
这是一个示例片段:
我很确定它不是未定义的,因为在调用foo
. 但是,如果我使用-Wall
标志编译代码,则会生成编译器警告,上面写着warning: operation on 'i' may be undefined
. 我意识到它说may
,但我只是想仔细检查一下我是否正确。
c - 序列点和副作用:C11 的悄然变化?
C99 §6.5表达式
(1) 表达式是一系列运算符和操作数,用于指定值的计算,或指定对象或函数,或产生副作用,或执行它们的组合。
(2) 在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。72)此外,应仅读取先验值以确定要存储的值。73)
带脚注
72) 浮点状态标志不是对象,可以在表达式中多次设置。
73) 本段呈现未定义的语句表达式,例如
同时允许
其中 C11 §6.5 更改为((1) 的文本有一个附录):
(1) […] 运算符的操作数的值计算在运算符结果的值计算之前排序。
(2) 如果标量对象的副作用相对于同一标量对象的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义。如果一个表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为是未定义的。84)
其中 C11 中的脚注 84 与 C99 中的脚注 73 相同。
我有点困惑...我将 C11 (2) 读为“[...] (对同一标量对象的不同副作用)或(使用同一标量对象的值的值计算)[...]”,这似乎甚至不允许foo = ++i
(有一个副作用,我们根据更改的对象使用一个值)。不过,我不是母语人士,所以如果有人能告诉我应该如何“解析”这句话,那就太好了。我了解C99,但我不太了解C11的措辞。
无论如何,实际的问题是:这是从 C99 到 C11 的变化,还是这些措辞是等价的?如果是这样,为什么它被改变了?如果没有,有人可以举一个表达式的例子,它在 C99 中是 UB,但在 C11 中不是,反之亦然?
c - 这个 C 语句的顺序是否明确定义?
标题有点模糊,因为我真的不知道如何定义这个问题。
它与以下代码有关:
for 循环中的语句是否保证按顺序运行?
例如,m_matchBase = match->requestedBase
保证在match = match->next
?
c++ - 序列点 && 运算符
对于C++03,标准规定, && 运算符的左右操作数之间存在一个序列点,因此在访问右运算符之前,左运算符的所有副作用都已发生。
所以
定义明确,保证输出0
。
但是这个问题是怎么回事:只有当左操作数不是时才评估右操作数0
?这似乎是一个细节,但对我来说,标准只保证操作数之间的序列点,而不是右操作数永远不会根据左操作数进行评估/访问。
例如
这定义好了吗?pos
可能是从开始10
或到达10
。左操作数没有与右操作数一致的副作用。我有arr[10] != 0
永不履行的保证吗?
编辑:
感谢评论和答案,现在很清楚:
是序列点的含义。
是短路的意思。
第一个没有第二个将使我的示例未定义。谢谢。
c - 如何检查c中未定义的行为?
我知道以下是未定义的,因为我试图在同一个表达式中读取和写入变量的值,即
但如果是这样,那么为什么下面的代码片段不是未定义的
就像这里一样,我也在尝试修改它的值a
并同时写入它。
还要解释为什么标准没有解决这个问题或删除这个未定义的行为,尽管他们知道它是未定义的?
c++ - 复合条件表达式中的排序
以下示例中的if
语句来自我正在尝试再次构建的旧项目。很抱歉,这不是一个可验证的样本,因为它不会重现错误,它自己编译得很好。
但是,在项目中,使用相同的编译(clang 3.3,除了包含路径之外没有其他选项),它给出了
(指向子表达式r = n - 1
)。项目中的if
语句(标记之间BEGIN-END
)是相同的,只是变量的类型可能不同。这里定义的类型只是粗略的近似,但我认为它们与警告并不真正相关。我已经能够将表达式简化为
同时仍然在项目中重现警告。
我的理解是,在评估 operator 的第一个操作数之后有一个序列点&&
(||
当没有重载时)。所以我无法解释警告。
如果对表达式的形式有任何想法,无论类型如何,那都会有所帮助。
编辑
使用 Vaughn Cato 的评论,我还发现
产生警告,而
才不是。S
实际上是一个模仿枚举的类,并且有一个自定义的底层类。它重载了按位运算符&
,|
以及!
用于掩码和隐式转换运算符到底层类型,在特定情况下是size_t
. 我不知道这有多大帮助,但我很抱歉没有从一开始就披露更完整的信息。
c++ - 在 c++ 中,赋值的一侧是否在另一侧之前排序?
我知道这是未定义的行为:
i
因为左侧和右侧的评估顺序未定义(这;
是唯一的序列点)。
进一步推理,在我看来,这将是不明确的未指定的行为:
=
尽管据我所知,右侧有几个序列点仍然是不明确的未指定是否先评估f()
或a[i]
先评估。
我的假设正确吗?当我在赋值的左侧使用全局或静态变量而右手在任何情况下都不会修改它时,我是否必须小心谨慎?