问题标签 [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.

0 投票
3 回答
304 浏览

c - 令人困惑的答案:一个说 *myptr++ 首先增加指针,另一个说 *p++ 取消引用旧指针值

如果您为我澄清这一点,我将不胜感激。这里有两个最近的问题及其已接受的答案:

1) C 中 *myptr++ 和 *(myptr++) 有什么区别

2) 又一个序列点查询:*p++ = getchar() 是如何工作的?

第一个问题的公认答案简明易懂地指出,由于++优先级高于*,因此首先完成指针的增量myptr,然后取消引用。我什至在编译器上检查并验证了它。

但是几分钟前发布的第二个问题的公认答案让我感到困惑。

它明确地说,*p++ 严格来说,旧地址p被取消引用。我没有理由质疑第二个问题的最高评价答案的正确性,但坦率地说,我觉得它与用户的第一个问题的答案相矛盾H2CO3。所以任何人都可以用简单明了的英语解释第二个问题的答案是什么意思以及为什么取消引用第二个问题中*p++的旧值。不应该首先递增,因为具有更高的优先级?到底如何才能在谢谢中取消引用旧地址。pp++*p++

0 投票
4 回答
407 浏览

c - 为什么逗号运算符似乎不能在我的代码中的“if”语句和“else”语句之间工作?

我知道像下面这样的语句(用逗号代替分号)看起来很奇怪:

但它工作得很好,我读过这是因为comma这里充当了一个序列点。我可以理解这一点。但我只是不明白为什么以下失败了,我也使用了 a else

它给出了错误expected expression before 'else'

为什么第二个语句会出错?在第一个语句中,我们看到它comma充当了一个序列点。那么为什么它之前没有这样做else呢?导致错误的第二种情况有什么特别之处?这是我的完整程序:

0 投票
1 回答
4807 浏览

c++ - 为什么我在 C++ 的语句表达式中得到“操作可能未定义”?

为了简单描述问题,请看下面的代码:

我从 [-Wsequence-point] 收到了这个警告

我的 g++ 版本是 4.4.5

谁能解释这个简单的问题,我将不胜感激。

顺便说一句,你可以在这个中文网站的#7中找到我的原始程序和原始问题(不是必需的)

UPD1:

虽然将代码更改为({if(a) a=0; a;})可以避免警告,但我认识到问题的真正原因可能不是The last thing in the compound statement should be an expression followed by a semicolon.

因为纪录片也说了If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value

一个例子可以显示它:

这段代码没有警告!所以我认为真正的原因是关于序列点。

请帮忙!

UPD2:

很抱歉@AndyProwl 不接受他在 UPD1 之前接受的答案。按照他的建议,我可能会问一个新问题(UPD1 是一个与原始问题不同的新问题)。我会再次接受他的回答,因为无论如何它肯定会避免警告。:)

如果我决定提出新问题,我将更新此问题以添加链接。

0 投票
3 回答
942 浏览

c - C中的序列点和副作用

在这个C-FAQ中给出了关于序列点的信息;

该标准规定;
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。

在示例中

从声明的第一句话可以清楚地看出,这些示例是导致未定义行为的结果。
在解释该声明的第二句话时,据说;

第二句话说:如果在一个完整的表达式中写入一个对象,那么在同一个表达式中对它的任何和所有访问都必须直接参与到要写入的值的计算中。该规则有效地将合法表达限​​制为那些访问明显先于修改的表达。例如,旧的备用

是允许的,因为 i 的访问用于确定 i 的最终值。这个例子

是不允许的,因为 i 的访问之一(a[i] 中的那个)与最终存储在 i 中的值无关(这在 i++ 中发生),因此没有好的方法来定义。

我的问题是;
1.这是什么意思,如果在一个完整的表达式中写入一个对象,那么在同一个表达式中对它的任何和所有访问都必须直接参与到要写入的值的计算中。?

2.这是什么意思,该示例a[i] = i++ 是不允许的,因为 i 的访问之一(a[i] 中的那个)与最终存储在 i 中的值无关(这在 i++ 中发生)
可以有人以某种简单的方式解释它吗?

0 投票
4 回答
659 浏览

c - 表达式a^=b^=a^=b中有序列点,还是未定义?

交换两个整数变量而不是使用临时存储的所谓“聪明”(但实际上效率低下)的方式通常涉及这一行:

但我想知道,复合赋值运算符^=不是序列点,是吗?这是否意味着它实际上是未定义的行为?

0 投票
3 回答
404 浏览

c++ - "(f(x))+g(y)" 是否可以确保在 C++ 中首先调用 f(x)?

并且f(x)+(g(y))可以确保g(y)先打电话吗?我知道表达式中的顺序在很多情况下是未定义的,但在这种情况下括号有效吗?

0 投票
1 回答
426 浏览

c - 未定义的行为和序列点

从过去几天开始,我试图了解未定义的行为。几天前,我找到了一个c-faq链接。这有助于消除许多困惑,但是当我阅读问题#3.8时又造成了另一个很大的困惑。经过我的大量努力来理解该陈述(特别是第二句);

该标准指出

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。

我觉得在 SO 上问这个问题更好,但那里的答案都没有解释这个陈述的第二句话。最后,我在那里得到了关于这一点的解释。在多次阅读它和常见问题解答后,我得出结论

1.最后一句话

此外,只能访问先验值以确定要存储的值

会是这样的;

此外,仅应访问对象的先前值以确定要存储的(同一对象的)修改/新值 。

正如示例所清楚的那样

在表达式的情况下,访问(在 RHS 中)的i = i + 1先验值(在1此处)i以确定i要存储的值。而在 and 的情况下j = i + 1a[i] = ii 的访问值只是值 而不是 先前值,因为i 在这些语句中没有修改 where 。

2.在表达式a[i] = i++或的情况下a[i++] = i,上述语句的第一句

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。

get failed因为 在两个连续的序列点之间i修改一次。这就是为什么我们需要第二句话。
这两个示例在 C 中都是不允许的,因为 i 访问了两次的先验值,即,i++ 它本身访问表达式中 的先验值i 来修改它,因此不需要其他访问先验值 /的值, i 因为它没有被访问以确定修改的要存储的值。

当我想出i = i++在 c-faq 中陈述 的表达式时,问题就开始了

实际上,我们一直在讨论的其他表达方式也违反了第二句话。

我认为在这个表达式i(在 RHS 中)被访问以确定i.
这个表达式如何违反第二个陈述?

0 投票
2 回答
81 浏览

c++ - 使用没有任何条件语句或在变量中捕获的逻辑运算符

我在一些代码库中看到了一种“诗意”的代码。虽然它看起来很直,但只是想确认它是否朝着正确的方向。
以非常简单的形式:

突出显示行的代码是否与下面的代码片段一样好?

我知道,调用所有语句的运算符,但不确定or(等效于||)运算符。
在 g++ 中测试,它给出了预期的输出

0 投票
2 回答
929 浏览

c++ - 函数调用的序列点?

这是另一个序列点问题,但相当简单:

这是未定义的行为吗?还是调用g(&p)充当序列点?

0 投票
3 回答
1296 浏览

c++ - 迭代器的 C++ 未排序修改

我在迭代器的一个单元测试中有下一个代码:

it尊重标准迭代器要求的地方。

据我所知,同一序列点中同一变量的 2 次修改是未定义的行为(!=不是序列点)。

考虑到这两个operator++版本都是具有return语句(序列点)的函数,未定义的行为是否适用于这些情况?如果不是,为什么我收到"Multiple unsequenced modifications to it"有关 Apple LLVM 5.0 编译器的警告?

当函数被内联时会发生什么(很可能它们会被内联!)?