可能错误使用了‘offsetof’宏

可能错误使用了‘offsetof’宏最近代码里引进了一个宏offsetof(s,m),原来一直在windows上开发,今天发现在linux编译的日志中出现了如下的警告:xxxx.cpp:8:警告:对NULL对象非静态数据成员‘XXX::xxx’的访问无效xxxx.cpp:8:警告:(可能错误使用了‘offsetof’宏)

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新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的时候会报警告,我就改个别的值好了…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/172096.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月22日 上午10:00
下一篇 2022年8月22日 上午10:00


相关推荐

  • 详解Spring Session

    详解Spring Session请求访问 tomcat gt tomact 检查请求的 sessionId gt 根据 sessionId 可以找到 session 对象 gt 使用该 session 对象创建 HttpServetRe 对象 gt 根据 sessionId 找不到 session 对象或者请求没有带 sessionId gt 创建一个 session 对象放进 Http

    2026年3月17日
    3
  • Winrar去广告图文教程「建议收藏」

    Winrar去广告图文教程「建议收藏」一、前言1.1Winrar解压缩工具  市场上有很多优秀的压缩工具,常用的有Winrar和360压缩工具。Winrar是免费压缩工具,特色是每次使用都会弹出广告。影响用户体验和工作效率,当然最重要的是影响心情。效果如下图。图1-1、Winrar弹广告效果图二、问题处理说明2.1问题解决方式  此处使用工具Resourcehacker对winrar.e…

    2022年5月2日
    63
  • 使用python代码画折线图【matplotlib】

    使用python代码画折线图【matplotlib】1、画折线图【一条示例】importmatplotlib.pyplotaspltimportnumpyasnpx_axis_data=[1,2,3,4,5,6,7]#xy_axis_data=[68,69,79,71,80,70,66]#yplt.plot(x_axis_data,y_axis_data,’b*–‘,alpha=0.5,linewidth=1,label=’acc’)#’bo-‘表示蓝色实线,数据点实心原点标注##plot中参数的含义分别

    2025年5月27日
    5
  • 即梦ai怎样导入外部素材 即梦ai文件上传格式要求

    即梦ai怎样导入外部素材 即梦ai文件上传格式要求

    2026年3月12日
    2
  • pyhcarm激活码(最新序列号破解)[通俗易懂]

    pyhcarm激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    83
  • java中重定向和转发的区别_java中转发和重定向的使用区别

    java中重定向和转发的区别_java中转发和重定向的使用区别java重定向和转发的区别response.sendredirect("http://www.foo.com/path/error.html");重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求,而浏览器将不会知道这个过程。与之相反,重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求。因为,当你使用重定向时,浏览器中所…

    2025年8月29日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号