2017-07-20 12 views
-2

私はXマクロ内でoffsetof()を使用した際に明らかなエラーが発生しました。以下のコードは、単純な構造の2つの例を示します.1つは明示的に定義され、もう1つはXマクロを使用して定義されます。両方の構造内の各構造フィールドのオフセットは、スクリーンに印刷されます。以下のコメントのように、Xマクロで定義された構造体のcフィールドは、誤ったオフセットを示しています。xマクロが間違ったoffsetof()情報を表示します

これは印刷の問題だと思います。誰かがこの謎に光を当ててくれますか?第2のXマクロで

#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; 
} 
+0

不適切な書式指定子を使用すると、定義されていない動作が発生します。 '%x'は符号なし整数で、'%d'は 'int'ですが、' offsetof'は 'size_t'を返します。 –

+0

あなたのXマクロは、 'offsetof(struct2、c [10])'を出力して終了します。これは、 'offsetof(struct1、c)'を行った最初の例とは異なります。 –

+0

問題が発生した場所。あなたは望みの結果を生み出すために私のxマクロを再定義する方法を考えることができますか? –

答えて

3

#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

上記のコメントの助けを借りて、私は答えを思いついた。配列である構造体要素に対しては、別のXマクロ定義が必要です。

#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  0x0008(00008) <== CORRECT 
      d  0x0030(00048) 

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

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

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

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

    return 0; 
} 
関連する問題