2012-11-08 28 views
8

可能重复:
Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?这是使用std :: array未定义的行为吗?

我使用charstd::array A S以保持未知原语类型,这是不超过10个字节长,像这样的一个值:

std::array<char, 10> val; 
*reinterpret_cast<double*>(val.data()) = 6.3; 
//blah blah blah... 
double stuff = *reinterpret_cast<double*>(val.data()); 

我读过那个来回穿越char *不是你吗ndefined,因为编译器假定一个char *可以别名任何类型的值。当这个值放在对象内部(我认为是)一个char s的数组时,这仍然有效吗?

注意:我知道我可以在这里使用联合,但这会导致我正在做的大量样板代码,并且如果有必要,我想避免它,因此是问题。

+0

不同的问题,相同的答案。 – Dan

+0

同样的问题,不同的单词。 ; - ] – ildjarn

回答

13

是,std::array< char, 10 >不符合double的对齐要求,因此reinterpret_cast会引起UB。

改为尝试std::aligned_storage

+0

对齐!当然,这是我甚至没有想到的。感谢那个链接,这正是我需要的。 – Dan

0

不要紧什么阵列包含在。

标准甚至不考虑什么东西包围(它是基本的),但不支持转换/从char序列。

要直接通过reinterpret_cast和赋值完成此操作,您需要使缓冲区正确对齐。

另一种方法是使用memcpy,它不关心对齐。

在一个相关的问题上,一般不是一个好主意,下降到二进制级别。例如,编译器的简单版本更改可能会使二进制序列化数据的文件无法访问。无论如何,做这件事的主要驱动因素是性能考虑。

+0

它支持将任意的char *转换为double *吗?我认为指针转换可能是有损的。考虑具有不同大小指针的ABI。 – Potatoswatter

+0

什么样的编译器更改会导致这种情况发生? – Dan

+0

'char'指针与任何指针都具有细粒度的寻址分辨率,与'void'相同。如果缓冲区没有正确对齐,指针转换可能是有损的。无论如何,数据复制可以*效率低下*。 –

相关问题