指针和后增加有趣的业务

时间:2011-11-28 15:35:55

标签: c++ c operator-precedence

这个c / c ++语句在理论上是错误的:

*memory++ = BIT_MASK & *memory;

其中BIT_MASK是任意按位AND掩码,而内存是指针。

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

2 个答案:

答案 0 :(得分:15)

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

您可以使用:

*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 ++标准中找到类似的措辞,但我不确定它是否与“附件C”类似。

答案 1 :(得分:6)

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

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

以下是两种解决方法:

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

或只是简单地说:

*memory++ &= BIT_MASK;

选择。