本文主要是介绍可能错误使用了‘offsetof’宏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
问题出现于实际工作当中,最近代码里引进了一个宏offsetof(s,m),这个宏的实际作用就是用来计算结构中的某个变量在结构中的偏移量的,实际的项目是跨平台的,原来一直在windows上开发,今天发现在linux编译的日志中出现了如下的警告:
xxxx.cpp:8: 警告:对 NULL 对象非静态数据成员‘XXX::xxx’的访问无效
xxxx.cpp:8: 警告:(可能错误使用了‘offsetof’宏)
这个问题实际测试下来仅仅是个警告,没有对程序运行产生影响,但对于多数拥有强迫症的程序猿来说,这是不可忍受的,必须把这个警告搞掉。
编码测试
- 简单代码测试
#include <stdio.h>
#include <stdlib.h>/* Define offsetof macro */
#ifdef __cplusplus#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif#else#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif#endif /* __cplusplus */struct STest
{int nValue1;int nValue2;int nValue3;static int nCount;char cValue4;char cValue5;STest(){nValue1 = 1;nValue2 = 3;}
};int main()
{STest test;test.nValue1 = 101;test.nValue2 = 110;test.nValue3 = 119;int n1 = offsetof(STest, nValue1);int n2 = offsetof(STest, nValue2);int n3 = offsetof(STest, nValue3);int n4 = offsetof(STest, cValue4);int n5 = offsetof(STest, cValue5);printf("n1 = %d\n", n1);printf("n2 = %d\n", n2);printf("n3 = %d\n", n3);printf("n4 = %d\n", n4);return 0;
}
其中关于offsetof的宏定义我是从stddef.h中复制出来的,这个文件是vs安装时自带的目录中发现的。
- 测试结果
- 分析
这个警告中的NULL比较扎眼,考虑把它搞掉们是不是只有NULL才会报警告呢,参考了其他平台和工具的offsetof宏定义,决定把当前环境中的offsetof宏定义改一下:
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
改成
#define offsetof(s,m) (size_t)(&reinterpret_cast<const volatile char&>((((s*)0x11)->m)) - 0x11)
改完后然后重新编译
- 第二次编译结果
总结
看来这g++编译器对NULL很敏感嘛!既然是0的时候会报警告,我就改个别的值好了…
这篇关于可能错误使用了‘offsetof’宏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!