x宏打印错误的offsetof()信息

时间:2017-07-20 02:56:06

标签: c macros printf c-preprocessor offsetof

我在X宏中使用offsetof()时出现了明显的错误。下面的代码显示了两个相当简单的结构示例,一个是显式定义的,另一个是使用X宏定义的。然后将两个结构内的每个结构场的偏移量打印到屏幕上。正如您在下面的注释中所看到的,使用X宏定义的结构中的 c 字段显示了不正确的偏移量。

我认为这是一个印刷问题。有人可以对这个谜团有所了解吗?

#include <stdio.h>
#include <stdlib.h>

const char fmt[] = "%-5s 0x%04x(%05d)\n";

#define i(s, f) \
    #f, \
    offsetof(s, f), \
    offsetof(s, f)

int main(void)
{
    /**********************************
    METHOD1 - CORRECTLY PRINTS

        a     0x0000(00000)
        b     0x0004(00004)
        c     0x0008(00008)
        d     0x0030(00048)

    **********************************/
    typedef struct {
        uint32_t a;
        uint32_t b;
        uint32_t c[10];
        uint32_t d;
    } struct1;

    printf(fmt, i(struct1, a));
    printf(fmt, i(struct1, b));
    printf(fmt, i(struct1, c));
    printf(fmt, i(struct1, d));

    printf("\n");

    /**********************************
    METHOD2 - PRINTS WRONG INFO

        a     0x0000(00000)
        b     0x0004(00004)
        c[10] 0x0030(00048)  <== WRONG
        d     0x0030(00048)

    **********************************/

    #define FIELDS \
        X(uint32_t, a,     "") \
        X(uint32_t, b,     "") \
        X(uint32_t, c[10], "") \
        X(uint32_t, d,     "") \

    typedef struct {
    #define X(type, name, descr) type name;
        FIELDS
    #undef X
    } struct2;

    #define X(type, name, descr) printf(fmt, i(struct2, name));
        FIELDS
    #undef X

    return 0;
}

2 个答案:

答案 0 :(得分:3)

在第二个X宏中:

  #define X(type, name, descr) printf(fmt, i(struct2, name));
  FIELDS

这扩展为:

printf(fmt, "a", offsetof(struct2, a), offsetof(struct2, a));
printf(fmt, "b", offsetof(struct2, b), offsetof(struct2, b));
printf(fmt, "c[10]", offsetof(struct2, c[10]), offsetof(struct2, c[10]));
printf(fmt, "d", offsetof(struct2, d), offsetof(struct2, d));

offsetof(struct2, c[10])显然与offsetof(struct2, c)不同。

答案 1 :(得分:-1)

在上述评论的帮助下,我想出了答案。对于作为数组的结构元素,我需要有一个不同的X-macro定义。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

mtcars = pd.read_csv("https://raw.githubusercontent.com/focods/WonderfulML/master/data/mtcars.csv")
sns.pairplot(mtcars, kind='reg', diag_kind='hist')