• offsetof宏的实现


    1、c语言的结构体中,因为字节对齐的问题,导致成员地址并不能根据类型的大小进行计算。例如:

    struct test {
        char ch;
        int a;
    }
    printf("test的大小=%d",sizeof(struct test));   //答案是8
    /*注意下面第二个char *,必须是char型指针(和结构体第一个成员类型一致),
    **因为你强制转换的是一个地址,所以必须用指针类型。
    **另外一个地址只有有了类型才可以进行加减运算,否在地址+1不知道要移动几个字节。
    */
    int *p=(int *)(char *)&test+1; //错误,因为char并不是占用1个字节,而是4个字节 int *p=(int *)(char *)%test+4; //正确

    2、offsetof宏的实现如下:

    #define offsetof(TYPE,MEMBER)   (size_t) &((TYPE *)0)->MEMBER)

    哈哈,复杂吧,解释一下:由于造成空洞的对齐动作是由编译器负责完成的,这里有一个欺骗编译器的指令:((TYPE *)0),

    意思是定义一个指向TYPE类型的指针,且该指针值(也就是该type类型的地址)为0,当然这是不可能引用成功的,0地址早已

    被操作系统保护起来了:),那么这么做意义何在?我们知道:当前地址-首地址=偏移量,如果首地址为0呢?当前地址是不是

    就是偏移量了?呵呵,明白了吧,强制把0转换为type类型的指针,并不是为了访问0地址的值,而是为了从编译器里套话(假设首地址

    为0时,当前地址是多少?)。

    最后要注意:因为我们得到的是一个地址,所以要设置为size_t类型,如果设为int类型,编译器就要警告了,因为int和size_t的大小不相同。

    最后以编译器的警告信息作为本文章的结尾吧:

    warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  • 相关阅读:
    XLS导出的服务器端配置方式
    SQLSERVER2008 内存占用高的处理方式
    word定义多级列表
    SQL Server替换特殊字符
    php和mysql两种不同方式的分割字符串和类型转换
    tp杂记
    MySql数据库 主从复制/共享 报错
    the server ssl certificate failed to verify
    loaded some nib but the view outlet was not set(转载)
    xcode7 调用相册权限无提示
  • 原文地址:https://www.cnblogs.com/litifeng/p/7685378.html
Copyright © 2020-2023  润新知