问题标签 [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++ - 由于 C 和 C++ 中的序列点,您遇到过哪些问题?
以下是由于序列点规则而导致未定义行为的两个常见问题:
关于序列点,您还遇到过哪些其他事情?
当编译器无法警告我们时,很难找出这些问题。
multithreading - 双重检查锁定的修复有什么问题?
因此,我现在看到很多文章声称在 C++ 双重检查锁定(通常用于防止多个线程尝试初始化延迟创建的单例)上已损坏。正常的双重检查锁定代码如下所示:
问题显然是行分配实例——编译器可以自由地分配对象,然后分配指针给它,或者将指针设置到它将被分配的位置,然后分配它。后一种情况打破了惯用语——一个线程可以分配内存并分配指针,但在它进入睡眠状态之前不运行单例的构造函数——然后第二个线程将看到实例不为空并尝试返回它,即使它尚未构建。
我看到一个建议使用线程本地布尔值并检查它而不是instance
. 像这样的东西:
这样,每个线程最终都会检查实例是否已创建一次,但在此之后停止,这会导致一些性能损失,但仍然没有锁定每个调用那么糟糕。但是如果我们只使用本地静态布尔值呢?
为什么这行不通?即使 sync_check 在被分配到另一个线程时被一个线程读取,垃圾值仍然是非零的,因此为真。Dobb 博士的这篇文章声称您必须锁定,因为您永远不会在重新排序指令上与编译器进行战斗。这让我认为由于某种原因这一定行不通,但我不知道为什么。如果对序列点的要求像 Dobb 博士的文章让我相信的那样丢失,我不明白为什么锁之后的任何代码都不能重新排序到锁之前。这将使 C++ 多线程中断期。
我想我可以看到编译器被允许专门将sync_check重新排序到锁之前,因为它是一个局部变量(即使它是静态的,我们也没有返回指向它的引用或指针)——但这仍然可以解决通过使其成为静态成员(实际上是全局的)来代替。
那么这会起作用还是不会呢?为什么?
c++ - 可以在调用构造函数之前完成赋值吗?
对双重检查锁定的修复有什么问题的评论?说:
问题是变量可能在构造函数运行(或完成)之前分配,而不是在分配对象之前。
让我们考虑代码:
为了进行更正式的分析,让我们将 a = new A 拆分为几个操作:
上面引用的评论是否属实,如果属实,在什么意义上?构造函数可以在赋值之后执行吗?如果可以,当因为 MT 安全而需要保证订单时,可以采取什么措施?
c++ - 这是“*ptr++ = *ptr + a”未定义的行为吗?
好吧,我并不是真的需要这个答案,我只是好奇。
像这样的表达式*ptr++ = a
是完全有效的,因为我们正在对两个对象进行操作ptr
,*ptr
但是如果我写*ptr++ = *ptr + a
它仍然有效吗?
例如,考虑以下代码段:
我认为表达式没有什么可担心的,*p++ = *p + 32;
但我不确定所涉及的序列点。
c++ - 没有序列点的 C++11?
维基百科说序列点在 C++11 中已被弃用。这意味着什么?这是否意味着由于序列点导致的未定义行为没有影响?
visual-c++ - 第一个条件下的变量赋值和第二个条件下使用相同的变量定义好?
这定义好了吗?
我相信我在某处读到,不能保证在第二个条件之前执行分配。可能是我错了,或者这仅适用于 C。
谷歌没有帮助我,这就是我在这里问的原因:)
c++ - 表达式的行为:已定义还是未定义?
我有以下代码
我的朋友告诉我,Expression A
他的行为定义明确,但我不确定他是否正确。
根据他的说法,函数在两者之间f()
引入了一个sequence point
,因此行为是明确定义的。
有人请澄清。
PS:我知道我们不应该出于实际目的编写这样的代码。只是为了学习。:)
c - 当 p 和 q 指向同一个对象时,“*p = ++(*q)”是否未定义?
在阅读了序列点之后,我了解到这i = ++i
是未定义的。
那么这段代码怎么样:
假设 p 和 q 的初始化是否取决于某些(复杂的)条件。并且它们可能像上述情况一样指向同一个对象。会发生什么?如果未定义,我们可以使用哪些工具来检测?
编辑:如果两个指针不应该指向同一个对象,我们可以使用 C99 限制吗?是“严格”的意思吗?
c - c中的序列点
命令式编程中的顺序点定义了计算机程序执行中的任何点,在该点处,可以保证先前评估的所有副作用都已执行,并且尚未执行后续评估的副作用。
这是什么意思?有人可以用简单的话解释一下吗?