可能错误使用了‘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的时候会报警告,我就改个别的值好了…

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 用户表的设计_角色和权限管理数据表设计

    用户表的设计_角色和权限管理数据表设计基于角色的访问控制:(javaWeb编程口诀)用户表角色表,用户角色中间表。角色表权限表,角色权限中间表。一个用户可有多个角色,一个角色又可有多个权限。这就是用户-角色-权限授权的模型。为何不直接让用户对应权限?角色=一定数量的权限集合将特定用户的权限封装到一个角色。封装,或者面向对象设计的体现。不足:此时,在用户之上加一个userGroup用户组的概念。可给单个用户授权或特定用户组授权。这样,一次授权,多个用户得到相同权限,此时用户所拥有的权限是用户个人权限+用户所在组权限用户组,用户与角色三者的关系

  • isalpha()方法可以检测字符串是否全为字母_isalpha()函数是什么意思

    isalpha()方法可以检测字符串是否全为字母_isalpha()函数是什么意思isalpha()方法描述Pythonisalpha()方法检测字符串是否只由字母组成。语法isalpha()方法语法:参数无。无。返回值如果字符串至少有一个字符并且所有字符都是

  • Qt 之图形(QPainter 的基本绘图)「建议收藏」

    Qt 之图形(QPainter 的基本绘图)「建议收藏」Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这三个类。-QPainter用于执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice显示图形(线、形状、渐变等)、文本和图像。

    2022年10月24日
  • python自动化办公——python操作Excel、Word、PDF集合大全[通俗易懂]

    python自动化办公——python操作Excel、Word、PDF集合大全[通俗易懂]Python操作Word、Excel、PPT、PDF\、复杂文件、通信软件(微信、邮件、飞书、钉钉)、图片目录  章节一:python使用openpyxl操作excel    1、openpyxl库介绍    2、python怎么打开及读取表格内容?       1)Excel表格述语       2)打开Excel表格并获取表格名称       3)通过sheet名称获取表格       4)获取表格的尺寸大小       5)获取表格…….

    2022年10月12日
  • ELK搭建的坑_elk技术栈

    ELK搭建的坑_elk技术栈ELK搭建的坑

    2022年10月20日
  • 外媒评论:原生 Android 已死

    外媒评论:原生 Android 已死

发表回复

您的电子邮箱地址不会被公开。

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