铸造时字节序是否重要
假设我有一个枚举,它只包含最多 0xFF 的值。我想将该枚举值放入一个字节变量中。AFAIK 枚举int
位于 (vxWorks) 下方。我正在编码的机器是大端。当我想将它放入 uint8_t 时,我不明白这是否重要。这些选项中哪些有效,哪些是最好的?
typedef enum {
kEnum1 = 0x00,
kEnum2 = 0x01,
kEnum3 = 0xFF
} MyEnum;
MyEnum myenum = kEnum3;
uint8_t mybyte = 0;
// option 1, do nothing
mybyte = myenum ;
// option 2, explicit cast
mybyte = (uint8_t)myenum;
// option 3, use operators
mybyte = (myenum & 0xFF000000) >> 24;
当我在一个我认为是小端的在线编译器上测试时,选项 3 当然不起作用。但其他人会。我只是不明白大端机器将如何对待这些选项。
回答
强制转换将值转换为新类型。C 2018 6.5.4 5 说“在带括号的类型名称的表达式之前将表达式的值转换为命名类型的非限定版本……”因此,如果枚举类型的表达式具有值 255 ( 0xFF
),则将其转换为uint8_t
产生值 255 作为类型的值uint8_t
。这对于可在目标类型中表示的任何算术值都是正确的。(如果该值不可表示,则可能会出现各种结果,包括换行、陷印、未定义行为和截断,具体取决于所涉及的类型。)
更详细地说,C 2018 在 6.3.1.3 中指定了整数类型之间转换的结果,枚举类型是一个整数(C 2018 6.2.5 16:“一个枚举包含一组命名的整数常量值……”)。6.3.1.3 1 说“当一个整数类型的值被转换为除 之外的另一个整数类型时_Bool
,如果该值可以用新类型表示,则它保持不变。”
用于表示枚举或其他对象的字节与转换无关,因为转换的结果是由值指定的,而不是表示。