【发布时间】:2015-02-10 09:05:29
【问题描述】:
在以下代码中摘自一段较大的代码
void func(int* usedNum, int wher) {
*usedNum = *usedNum + 1 > wher ? ++(*usedNum) : wher + 1;
}
int main(void) {
int a = 11, b = 2;
func(&a, b);
}
警告是emitted
warning: operation on '* usedNum' may be undefined [-Wsequence-point]
*usedNum = *usedNum + 1 > wher ? ++(*usedNum) : wher + 1;
代码有问题吗?
我的怀疑来源是this 以及它所说的部分
&&、||等逻辑表达式中的序列点三元运算符 ?: 和逗号运算符表示左侧操作数在右侧操作数之前计算。这几个操作数是 C++ 中唯一引入序列点的操作数。
tl;博士
对于那些在阅读 cmets 时感到折磨的人:最初的问题没有正确提出,造成误解是不公平的。我对这个话题的看法有两个方面
-
三元运算符不会(以意想不到的方式)弄乱序列点(这两个分支在每个版本的 C、C++ 中都是有序的 - 请参见提供的链接)
李> x = ++x有问题吗?如 coliru 链接所示,我们为 c++14 编译。那里的操作定义良好(对 cmets 的引用),但旧版本的 c++ 和 c 将其视为未定义。那么为什么会有警告呢?
答案集中在 C 和 C++; this 是一个很好的链接。最后,C 标记最初存在(我的错误)并且无法删除,因为现有的赞成答案引用它
【问题讨论】:
-
不就是说
x = ++x吗?所以是的,如果遵循truthy分支,潜在的UB。 -
@juanchopanza 不等于说
x = (++x)吗?根据this,哪个定义明确? (看看上面写着i = (++i,i++,i) // well defined的部分) -
逗号运算符引入序列点。您问题中的代码没有逗号运算符。
-
这看起来像 C++,为什么是 C 标签?
-
是的,这意味着
a在b或c之前在a ? b : c中被评估,但这并不意味着整个事情在分配的LHS 之前被排序。跨度>