指针和自增后操作
Pointer and post-increment funny business
这个c/c++语句在理论上有什么问题?
*memory++ = BIT_MASK & *memory;
其中BIT_MASK
为任意位AND
掩码,内存为指针。
目的是读取内存位置,AND
值与掩码,存储结果在原始位置,然后最后增加指针指向下一个内存位置。
您正在调用未定义的行为,因为您在没有中间序列点的单个语句中引用memory
两次(一次用于读取,一次用于写入),并且语言标准没有指定何时会发生增量。(你可以多次读取相同的内存;当您试图将一些书写与阅读混合在一起时,就会出现问题-就像您的示例一样。
你可以使用:
*memory++ &= BIT_MASK;
实现你想要实现的目标,而不会产生未定义的行为。
在C标准(ISO/IEC 9899:1999又名C99)中,§6.5 'Expressions',¶2表示
在前一个序列点和下一个序列点之间的是对象的存储值通过表达式的求值最多修改一次。进一步,先验值70)
这是C标准的主要来源。脚注说:
这个段落呈现未定义的语句表达式,如
i = ++i + 1; a[i++] = i;
同时允许
i = i + 1; a[i] = i;
此外,"附录C(信息性)序列点"对所有这些进行了广泛的讨论。
你会在c++标准中找到类似的措辞,尽管我不确定它是否有类似的"附录C"。
这是未定义的行为,因为您在同一语句中有memory++
和memory
。
这是因为C/c++没有指定++
发生的确切时间。它可以在*memory
求值之前或之后。
*memory = BIT_MASK & *memory;
memory++;
或者直接:
*memory++ &= BIT_MASK;
相关文章:
- 迭代器的指针操作问题
- 我试图了解在异或操作后指针变量正在更改
- 通过浮点指针操作字节向量
- 使用 XOR 操作仅使用 2 个指针反转链表
- 为什么指针在由后增量比较器操作时行为不同?
- 指针 OOP 操作
- C++数组指针上的删除操作
- 如何有效地使用 std::async 对指针数组执行操作
- 为什么在执行增量操作之前分配指针值
- 是否可以使用C++函数指针,如 C# 的操作?
- 共享指针,C 版本的原子操作
- 普通指针,连同通常的操作 & 和 *,是 monad 吗?
- 双指针 **src 和操作 (*(*src)++ = reg_offset)
- 调用向量内的函数指针不执行任何操作
- 调用 vector.erase() 函数时指针操作无效错误
- 即使在单线程程序中,共享指针是否在引用计数中使用原子操作
- C 弦乐操作用指针,中间为空
- 尝试仅通过操作指针对链表进行排序
- 在类内部操作指针
- 仅通过操作指针交换链表中的相邻节点