gpt4 book ai didi

C++ 类型别名,其中值被替换

转载 作者:行者123 更新时间:2023-11-28 01:28:42 25 4
gpt4 key购买 nike

以下代码在 C++ 中是否合法?

int get_i(int idx) { ... }
float transform(int i) { ... }
void use(float f) { ... }

static_assert(sizeof(int) == sizeof(float));
void* buffer = std::malloc(n * sizeof(int));

int* i_buffer = reinterpret_cast<int*>(buffer);
float* f_buffer = reinterpret_cast<float*>(buffer);

// Fill int values into the buffer
for(int idx = 0; idx < n; ++idx)
i_buffer[idx] = get_i(idx);

// Transform int value to float value, and overwrite
// (maybe violates strict aliassing rule?)
for(int idx = 0; idx < n; ++idx)
f_buffer[idx] = transform(i_buffer[idx]);

for(int idx = 0; idx < n; ++idx)
use(f_buffer[idx]);

第二步将缓冲区值读取为int,然后在其位置写入一个float。之后它再也不会通过 i_buffer 访问内存,因此读取时没有类型别名。

然而,赋值 f_buffer[idx] = 将一个 float 对象写入一个 int 对象,即 UB。

有没有办法让编译器认为这意味着 int 的生命周期应该结束,并且应该在它的位置构造一个 float 对象,所以没有类型别名?

最佳答案

However the assignment f_buffer[idx] = writes a float object into an int object, which is UB.

是的,上面的代码中断了 type aliasing rules .

要解决这个问题,对于您的值(value)观,您可以使用 union :

union U {
float f;
int i;
};

然后访问对应的 union 成员。

这样当你做的时候:

buffer[idx].i = ...; // make i the active union member
...
buffer[idx].f = transform(buffer[idx].i); // make f the active union member

它避免了 UB,因为 buffer[idx].i 的生命周期结束,buffer[idx].f 的生命周期开始。

关于C++ 类型别名,其中值被替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52643654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com