指针和后增加有趣的业务

5 c c++ operator-precedence

这个c/c ++语句在理论上是错误的,如果有的话:

*memory++ = BIT_MASK & *memory;
Run Code Online (Sandbox Code Playgroud)

哪个BIT_MASK是任意按位AND掩码,而内存是指针.

目的是读取内存位置,AND使用掩码的值,将结果存储在原始位置,然后最终将指针递增以指向下一个内存位置.

Jon*_*ler 15

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

您可以使用:

*memory++ &= BIT_MASK;
Run Code Online (Sandbox Code Playgroud)

实现您想要实现的目标而不会产生未定义的行为.


在C标准(ISO/IEC 9899:1999又名C99)中,§6.5'表达式',2表示

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.70)

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

此段落呈现未定义的语句表达式,如

i = ++i + 1;
a[i++] = i;
Run Code Online (Sandbox Code Playgroud)

允许的同时

i = i + 1;
a[i] = i;
Run Code Online (Sandbox Code Playgroud)

此外,'附件C(资料性)序列点'对所有这些进行了广泛的讨论.

您会在C++标准中找到类似的措辞,但我不确定它是否与"附件C"类似.

  • @Benjamin:美丽在旁观者的眼中; 我更喜欢单语句版本. (4认同)
  • 或者,更好的是:`*memory&= BIT_MASK; ++存储器;` (3认同)

Mys*_*ial 6

它是未定义的行为,因为你有memory++memory在同一个语句中.

这是因为C/C++没有准确指定何时++发生.它可以在*memory评估之前或之后.

以下是两种修复方法:

*memory = BIT_MASK & *memory;
memory++;
Run Code Online (Sandbox Code Playgroud)

或者只是简单地:

*memory++ &= BIT_MASK;
Run Code Online (Sandbox Code Playgroud)

随便挑选.