指针和后自增的搞笑事
如果有的话,这个 c/c++ 语句在理论上是错误的:
*memory++ = BIT_MASK & *memory;
其中 BIT_MASK
是任意按位 AND
掩码,内存是一个指针。
目的是读取内存位置,将值与掩码进行“与”操作,将结果存储在原始位置,然后最后递增指针以指向下一个内存位置。
What, if anything, is theoretically wrong with this c/c++ statement:
*memory++ = BIT_MASK & *memory;
Where BIT_MASK
is an arbitrary bitwise AND
mask, and memory is a pointer.
The intent was to read a memory location, AND
the value with the mask, store the result at the original location, then finally increment the pointer to point to the next memory location.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在调用未定义的行为,因为您在单个语句中引用了两次内存(一次用于读取,一次用于写入),而没有插入序列点,并且语言标准未指定何时发生增量。 (您可以多次读取相同的内存;当您尝试将一些写入与读取混合时,就会出现麻烦 - 正如您的示例所示。)
您可以使用:
来实现您想要实现的目标,而不会导致未定义的行为。
在 C 标准(ISO/IEC 9899:1999 又名 C99)中,§6.5“表达式”,¶2 说
这是 C 标准中的主要来源。脚注说:
此外,“附件C(信息性)序列点”对所有这些进行了广泛的讨论。
您会在 C++ 标准中找到类似的措辞,尽管我不确定它是否与“Annex C”类似。
You are invoking undefined behaviour because you reference
memory
twice (once for reading, once for writing) in a single statement without an intervening sequence point, and the language standards do not specify when the increment will occur. (You can read the same memory multiple times; the troubles occur when you try to mix some writing in with the reading - as in your example.)You can use:
to achieve what you want to achieve without incurring undefined behaviour.
In the C standard (ISO/IEC 9899:1999 aka C99), §6.5 'Expressions', ¶2 says
That's the primary source in the C standard. The footnote says:
In addition, 'Annex C (informative) Sequence Points' has an extensive discussion of all this.
You would find similar wording in the C++ standard, though I'm not sure it has an analogue to 'Annex C'.
这是未定义的行为,因为您在同一语句中有
memory++
和memory
。这是因为 C/C++ 没有具体指定
++
何时发生。它可以在*memory
求值之前或之后。这里有两种解决方法:
或者只是简单地:
选择你自己的。
It's undefined behavior since you have
memory++
andmemory
in the same statement.This is because C/C++ does not specify exactly when the
++
will occur. It can be before or after*memory
is evaluated.Here are two ways to fix it:
or just simply:
Take your pick.