大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
前言
问题出现于实际工作当中,最近代码里引进了一个宏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的时候会报警告,我就改个别的值好了…
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/172096.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...