问题标签 [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 投票
4 回答
2851 浏览

c++ - 为什么表达式 a = a + b - ( b = a ) 在 c++ 中给出序列点警告?

以下是测试代码:

编译它会给出以下警告:

为什么操作可以是未定义的?

根据我的理解,首先(b = a)应该评估子表达式,因为()的优先级更高,因此设置b = a。然后,由于 '+' 和 '-' 具有相同的优先级,表达式将被左关联评估。因此,a + b接下来应该评估,最后(b = a)应该从 中减去的结果a + b。我看不到这里违反了任何序列点规则。

0 投票
6 回答
637 浏览

c - 分配和序列点:这怎么模棱两可?

考虑 C 代码a = a = a。没有用于赋值的序列点,因此此代码在编译有关a.

这里可能有什么价值a?似乎a不可能改变价值观。这里实际上是否存在未定义的行为,或者编译器只是懒惰?

0 投票
2 回答
941 浏览

c++ - 在返回对象的函数调用和对该对象的方法调用之间是否存在序列点?

如果我写,我可以在评估之前f(x)->g(args, ...)依赖一个序列点吗?我可以看到两种方式的论点:f(x)args, ...

  • §1.9.17 “在调用函数时(无论该函数是否内联),在函数体中的任何表达式或语句执行之前发生的所有函数参数(如果有)的评估之后都有一个序列点。在复制返回值之后和函数外的任何表达式执行之前还有一个序列点。
  • 另一方面,对象指针隐含地是一个隐藏的参数this,就好像我写g(f(x), args, ...)的那样,这表明它就像一个参数,因此未指定。

->运算符不是普通的二元运算符,因为显然g(...) 无法f(x)像我写的那样进行评估f(x) + g(...)。我很惊讶我找不到一些关于它的具体陈述。

0 投票
2 回答
353 浏览

c - return 语句后的序列点?

在我对一个问题的回答中,我解释了在与return语句在同一行的全局变量上使用后缀 ++ 时发生的情况。

C11 的资料性附录 C 指出在 a 之后有一个序列点,return并参考规范性章节 6.8.6.4,其中没有关于序列点的文本。

在 C 标准中,我可以在哪里找到说明语句后有序列点的规范性文本return

(作为特例,我只在 7.1.4/3 找到了说明库函数的规范文本。)

0 投票
1 回答
300 浏览

c++ - 为什么对原始类型的操作是未排序的,而不是不确定排序的?

If iis an int, 像这样的表达式++i + ++i是未定义的行为,因为有 2 个未排序的修改i. 但是, ifi是一些int类似的类,++i + ++i而是具有不确定的顺序修改,因此是定义的行为(在这种情况下具有确定性的结果)。有没有一种情况,对原语的操作最好是无序列的而不是不确定的序列?如果是这样,为什么这种情况不适用于用户创建的类型?如果不是,为什么原始操作根本没有排序?

0 投票
2 回答
256 浏览

c++ - 是索引一个新的地图元素并将读取它的东西分配给它未定义的行为,还是只是未指定?

在回答了这个问题之后,关于有问题的代码是否是未定义的行为进行了长时间的讨论。这是代码:

首先,这是公认的,这至少是未指定的。结果根据首先评估作业的哪一侧而有所不同。在我的回答中,我跟踪了四个结果案例中的每一个,其中首先评估了哪一方的因素以及该元素在此之前是否存在。

还出现了一个简短的表格:

我声称它更像这样:

最终,我找到了一个似乎对我有用的例子:

回到原来的,我把它分解成相关的函数调用,以便更容易理解:

如果word_count["a"]不存在,则有人认为它将被分配两次,而两者之间没有排序。如果我认为是真的两件事实际上是:

  1. When a side is picked to be evaluated, the whole side has to be evaluated before the other side can start.

  2. 诸如 word_count["a"] = 1 之类的结构表现出明确定义的行为,即使在插入元素然后分配给它的情况下也是如此。

这两个说法是真的吗?最终,这实际上是未定义的行为吗?如果是,为什么第二个语句起作用(假设它起作用)?如果第二个是假的,我相信myMap[i]++;世界上所有的 s 都是不正确的。

有用的链接:未定义的行为和序列点

0 投票
1 回答
1009 浏览

c - int a=1, b=a++; 调用未定义的行为?

是否int a=1, b=a++;调用未定义的行为?a的初始化及其在初始化程序中的访问和修改之间没有序列点干预b,但据我所知,初始化不是对象的“修改”;指定一个初始化器来给出对象的“初始值”。根据 6.7.8 初始化,第 8 段:

初始化器指定存储在对象中的初始值。

并且在对对象的任何访问之前将“初始”作为排序似乎是合理的。以前是否考虑过这个问题,是否有公认的解释?

0 投票
2 回答
255 浏览

c - 像“int a=4,*ptr=&a;”这样的语句是否存在“序列点”问题 还是“x+=4,y=x*2;”?

我对整个序列点的理解是基本的。我所拥有的只是一些粗略的直观想法,即“一旦遇到序列点,我们可以确定之前评估的所有副作用都是完整的”。我还读到,在printf("%d",a++,++a,a++)行为未定义之类的语句中,逗号不表示序列点,而分号表示。因此,与其凭直觉进行猜测和猜测,我觉得一个非常严谨和确凿的答案会对我有很大帮助。

以下类型的语句在 C 中是安全且确定的:

如果是,如何?特别是在第二种情况下,如果逗号不是序列点,我们如何确定在赋值中使用它之前x已经递增了?对于第一条语句,我如何确定在分配地址之前已经初始化并分配了内存?我应该安全地使用以下内容:4y=x*2aptr

编辑我对逗号运算符的理解告诉我这些语句是安全的。但是在阅读了关于序列点以及类似的东西printf("%d",a++,++a,a++)是如何未定义的之后,我有了第二个想法。

0 投票
4 回答
313 浏览

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

§5.1.2.4.16

示例 7 表达式的分组并不能完全确定它的求值。在以下片段中:

表达式语句被分组,就好像它被写成

但是 p 的实际增量可以发生在前一个序列点和下一个序列点( ; )之间的任何时间,并且对 getchar 的调用可以在需要其返回值之前的任何时间发生。

所以基本上我将其理解为未指定的行为-要​​么*p = getchar(); p++;OR p++; *p = getchar()。请注意,这;意味着一个序列点,但整个表达式中没有其他序列点。

所以这个语法是没用的。而且,对于指针赋值,++ 和 -- 几乎是没用的。正确的?

0 投票
2 回答
1972 浏览

c - 像 "for(i=1;i<=10;printf("%d\n";i),i++) 这样的东西在 C 中是否有效且无 UB?

以下两个代码块是否完全相同并实现相同的东西?当我运行程序时它显示相同的东西,但我希望能得到一些严格的解释。

循环需要有效的forC 语句作为参数,不是吗?但是,即使我已经在 StackOverflow 上验证了类似语句x+=4,y=x*2;是安全的,因为这里的逗号充当序列点,但在上面的循环printf("%d\n",i),i++)中作为参数传递的语句是否相同?for

如果是,请费心回答由此产生的小问题:

  • 是否comma充当涉及许多逗号分隔的语句中的序列点

    函数调用如下:

    printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);