我正在管理一个由4个uint8_t标志组成的数组。
uint8_t flags[4].
这些标志随时可以通过不同的线程进行更改。
我希望能够通过一个原子操作获得这些标志的快照。 让我说我做以下事情:
uint32_t temp_val = read_atomic32((uint32_t *) &flags[0])
现在我回到了一系列标志:
uint8_t *my_flags = &temp_val;
printf("flag zero is %d\n, my_flags[0]);
我怀疑这里几乎没有问题:
也许标志[4]没有与uint32_t读取对齐,并且可能会导致非对齐崩溃 或者,由于访问不对齐,原子功能不会被占用。
端序员怎么样?如果出现问题?即使我正在使用uint32_t我稍后将其转换回uint8_t数组,我不认为内存布局会因为这个动作而改变 - 但是,也许我在这里遗漏了一些东西。 我在这里假设,如果我读取4字节的内存位置,无论你的机器是小端还是大端,这些模式都是相同的,直到退回。
有没有更好的方法来管理uint8_t的4个独立标志,但仍然能够以便携式安全方式使用一个动作完整地读取它们?
答案 0 :(得分:2)
将你的旗帜放在一个联盟中:
union {
uint8_t c[4];
uint32_t t;
} flags;
flags.c[0] = ...;
flags.t = 0xffffffffU;
这会解决对齐问题,您可以使用类型双关语来通过t
访问标记而无需强制转换。根据严格的ISO C规则,不完全是犹太洁食,但通常会做你想要的。
当您分配文字值时(如我的示例中)或在访问flags.t
时期望某些值时,字节顺序会成为问题。只是阅读一个值,然后写一个只读(未经修改 - 没有一点点!)应该没问题。