指针和后自增的搞笑事

发布于 2024-12-18 07:34:01 字数 225 浏览 0 评论 0原文

如果有的话,这个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

诗酒趁年少 2024-12-25 07:34:01

您正在调用未定义的行为,因为您在单个语句中引用了两次内存(一次用于读取,一次用于写入),而没有插入序列点,并且语言标准未指定何时发生增量。 (您可以多次读取相同的内存;当您尝试将一些写入与读取混合时,就会出现麻烦 - 正如您的示例所示。)

您可以使用:

*memory++ &= BIT_MASK;

来实现您想要实现的目标,而不会导致未定义的行为。


在 C 标准(ISO/IEC 9899:1999 又名 C99)中,§6.5“表达式”,¶2 说

在上一个和下一个序列点之间,对象应具有其存储值
通过表达式的求值最多修改一次。此外,先验值
应只读以确定要存储的值。70)

这是 C 标准中的主要来源。脚注说:

本段呈现未定义的语句表达式,例如

<前><代码>i = ++i + 1;
a[i++] = i;

在允许的情况下

<前><代码>i = i + 1;
a[i] = i;

此外,“附件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:

*memory++ &= BIT_MASK;

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

Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.70)

That's the primary source in the C standard. The footnote says:

This paragraph renders undefined statement expressions such as

i = ++i + 1;
a[i++] = i;

while allowing

i = i + 1;
a[i] = i;

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'.

木緿 2024-12-25 07:34:01

这是未定义的行为,因为您在同一语句中有 memory++memory

这是因为 C/C++ 没有具体指定 ++ 何时发生。它可以在*memory 求值之前或之后。

这里有两种解决方法:

*memory = BIT_MASK & *memory;
memory++;

或者只是简单地:

*memory++ &= BIT_MASK;

选择你自己的。

It's undefined behavior since you have memory++ and memory 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:

*memory = BIT_MASK & *memory;
memory++;

or just simply:

*memory++ &= BIT_MASK;

Take your pick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文