c - 严格别名警告:将 uint64_t 变量类型转换为 64 位大小的结构
问题描述
我正在努力解决 Linux (4.19.21-linux-gnu-gcc) 上的 C 程序中的以下问题,
//Structure definition :
struct data_from_u64 {
uint32_t u32_value;
uint16_t u16_value;
uint8_t u8_value1;
uint8_t u8_value2;
}
//Expectation : Convert a incoming uint64_t variable to the above structure using the below macro,
#define U64_TO_STRUCT(u64_value) ( * (data_from_u64 *) ((void*) &(u64_value)) )
//Usage
data_from_u64 data = U64_TO_STRUCT(u64_value);
项目很大,应用非常广泛,但新的编译程序在编译时强制执行“-O2”和“-Werror”标志。您能否帮助解决下面提到的错误/警告。更改应该是最小的,因为这个宏在 1000 多个地方使用。
错误/警告:
错误:取消引用类型双关指针将破坏严格别名规则 [-Werror=strict-aliasing] #define U64_TO_STRUCT(u64_value) ( * (data_from_u64 ) ((void ) &(u64_value)) )
我尝试了什么:
我试过做memcpy,它有效。但它需要在所有 1000 个使用位置进行更新[它需要更改宏的参数以包含目标]。
解决方案
你可以使用这个:
struct data_from_u64 U64_TO_STRUCT(uin64_t u64_value) {
struct data_from_u64 ret;
memcpy(&ret, &u64_value, sizeof u64_value);
return ret;
}
不能返回这样的结构是一个常见的误解。您不能返回本地数组,但返回结构非常好。
从中吸取的教训是,我们在 SO 的所有关于“你违反了抗锯齿规则”的唠叨不仅仅是一些在实践中无关紧要的书呆子胡说八道。正如您自己所看到的,它确实会产生现实世界的后果。:)
如果您真的想为此使用宏,请查看Eric 的答案,该答案效果很好,符合标准并且不依赖于编译器扩展。我个人只是不喜欢宏之类的功能。
推荐阅读
- php - php 中的 mysqli 类偶尔无法加载
- maven - Nexus 存储库中的工件问题
- reactjs - 处理与 react/next api 调用的不一致
- android - 片段中 ListView 的自定义适配器不起作用
- html - If i uninstall chinese "SimSun" and "Mingliu" font, what is the default font that it will show?
- python - 为什么使用 gzip 重新压缩文件会产生不同的输出?
- nxp-microcontroller - Stepping over a library (in-built) function in NXP FXTH870911
- javascript - 如何在 React 中显示来自 API 的数据
- python - ContractLogicError while using web3.py
- ios - 如何知道用户是否完成在 PDFView 中选择文本