我想以便携方式(C99)将一种类型的数据重新解释为另一种类型.我不是在谈论铸造,我想重新解释一些给定的数据.此外,通过便携式我的意思是它不会破坏C99规则 - 我并不是说重新解释的值在所有系统上都是相同的.
我知道3种不同的重新解释数据的方法,但其中只有两种是可移植的:
这不是便携式的 - 它打破了严格的别名规则.
/* #1 Type Punning */
float float_value = 3.14;
int *int_pointer = (int *)&float_value;
int int_value = *int_pointer;
Run Code Online (Sandbox Code Playgroud)这是依赖于平台的,因为它int
在写入之后从联合中读取值float
.但它不会破坏任何C99规则,所以它应该工作(如果sizeof(int) == sizeof(float)
).
/* #2 Union Punning */
union data {
float float_value;
int int_value;
};
union data data_value;
data_value.float_value = 3.14;
int int_value = data_value.int_value;
Run Code Online (Sandbox Code Playgroud)应该没问题,只要 sizeof(int) == sizeof(float)
/* #3 Copying */
float float_value = 3.14;
int int_value = 0;
memcpy(&int_value, &float_value, sizeof(int_value));
Run Code Online (Sandbox Code Playgroud)我的问题:
Chr*_*oph 18
解决方案2 是便携式的 - 通过工会进行类型的惩罚在C99中一直是合法的,并且TC3明确说明了这一点,它在6.5.2.3节中添加了以下脚注:
如果用于访问一个联合对象的内容的部件是不一样的最后用于存储在该对象的值的部件,所述值的对象表示的适当部分被重新解释为在新类型作为对象表示在6.2.6中描述(一个过程有时称为"类型双关语").这可能是陷阱表示.
附件J仍将其列为未指明的行为,这是一个已知的缺陷,并已用C11进行了更正,后者发生了变化
存储在[ 未指定 ]中的最后一个以外的联合成员的值
至
对应于工会成员的字节值,而不是最后存储到[ 未指定的 ]
这并不是什么大不了的事,因为附件只是提供信息,而不是规范性的.
请记住,您仍然可以最终得到未定义的行为,例如