这个c / c ++语句在理论上是错误的:
*memory++ = BIT_MASK & *memory;
其中BIT_MASK
是任意按位AND
掩码,而内存是指针。
目的是读取内存位置,AND
使用掩码的值,将结果存储在原始位置,然后最后将指针递增以指向下一个内存位置。
答案 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;
选择。