C宏判断处理器字节序报错:‘*’无左操作数求解决
问题解决:字节序判断宏报错‘*’没有左操作数
错误原因
你编写的宏直接对字符串字面量进行强制类型转换并解引用,存在两个核心问题:
- 字符串字面量是
const char[]类型,强制转换为uint16_t*属于非const到const的反向类型转换,违反类型安全规则; - 这种直接操作字符串字面量内存的写法属于C标准中的未定义行为,部分编译器会因此抛出“*没有左操作数”的语义错误。
正确实现方案
以下两种方式均符合C标准,兼容性更好:
方案1:复合字面量法(简洁高效)
利用复合字面量创建临时变量,直接读取内存布局判断字节序:
#include <stdint.h> // 判断是否为小端字节序(小端返回1,大端返回0) #define IS_LITTLE_ENDIAN() (1 == *(uint8_t*)&(uint16_t){1}) // 判断是否为大端字节序(大端返回1,小端返回0) #define IS_BIG_ENDIAN() (0 == *(uint8_t*)&(uint16_t){1})
原理:创建值为1的uint16_t变量,小端模式下最低地址的字节存储1,大端模式下最高地址的字节存储1,通过读取最低地址字节的值即可判断。
方案2:联合体法(直观易懂,符合标准)
通过联合体共用内存的特性,观察uint16_t和uint8_t数组的对应关系:
#include <stdint.h> #define ORDER_LE ({ \ union { \ uint16_t u16; \ uint8_t u8[2]; \ } endian = { .u8 = {0, 1} }; \ endian.u16 >> 8; \ }) #define ORDER_BE ({ \ union { \ uint16_t u16; \ uint8_t u8[2]; \ } endian = { .u8 = {1, 0} }; \ endian.u16 >> 8; \ })
原理:联合体中u16和u8共用同一块内存,初始化u8数组后,右移u168位即可得到高位字节的值,以此判断字节序。
注意事项
- 必须包含
<stdint.h>头文件,否则uint8_t、uint16_t等类型无法识别; - 方案1中的复合字面量是C99标准特性,若需兼容更老的C标准,建议使用方案2或静态数组写法。
内容的提问来源于stack exchange,提问作者Penguin
相关产品推荐
相关产品推荐

