可能错误使用了‘offsetof’宏

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


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)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Vue父组件向子组件传值简单示例「建议收藏」

    Vue父组件向子组件传值简单示例「建议收藏」在Vue中父组件向子组件传值。首先在父组件中将要传递的变量赋值给子组件<子组件:变量=数据></子组件>然后子组件中定义props变量props:[‘变量’]具体例子如下:首先在components中创建三个组件Header.Vue、Swiper.Vue、Footer.Vue,然后在App.Vue中引入组件并定义要传递的数据。这里主要是将a数据传递给Header,arr传递给Swiper<template> <div> <

    2022年6月5日
  • gitee pycharm_怎么把git上放到pycharm

    gitee pycharm_怎么把git上放到pycharm好久没有使用git,都忘记git的操作流程了,只能强制回忆一下:今天接到领导通知,要把我这边写的代码提交到远程仓库,然后就想,他那边仓库里的代码源码都是我提供的,我本地在pycharm中也是添加了git管理的,所以就想直接我这边的仓库代码直接push到远程仓库上去,先pull,然后在push就行了,结果搞了半天,一直提示我这边的版本在远程仓库之前的版本:hint:Updateswererejectedbecausethetipofyourcurrentbranchisbehi

    2022年8月28日
  • 数据挖掘十大算法之CART详解

    数据挖掘十大算法之CART详解在2006年12月召开的IEEE数据挖掘国际会议上,与会的各位专家选出了当时的十大数据挖掘算法(top10dataminingalgorithms),本博客的十大数据挖掘算法系列文章已经介绍了其中的六个,本文主要讨论CART,即分类回归树(ClassificationAndRegressionTree),一个具体的例子将帮助大家更好地理解相关内容

    2022年6月6日
  • C++通过TinyXML类库读写XML文件

    C++通过TinyXML类库读写XML文件TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。

    2022年4月30日
  • Xshell修改终端字符编码【解决Linux日志中日志乱码】

    Xshell修改终端字符编码【解决Linux日志中日志乱码】

    2021年6月1日
  • 【kubernetes集群系列(一)】Master安装(使用kubeadm)

    【kubernetes集群系列(一)】Master安装(使用kubeadm)

    2021年5月13日

发表回复

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

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