2013-09-23 30 views
1

使用參數我有一個下面的typedefC近拍取決於類型

typedef struct { 
     const char *name; 
     void *variable; 
     int type; 
     int *present; 
    } parse_t; 

和具有可變和具有所附的_b相同名稱的整數的結構。

例如:

typedef struct { 
    char test[12]; 
    int test_b; 

    long id; 
    int id_b; 

    } record_t; 

我試圖做的是定義在parse_t結構,將它取決於變量的類型寫入記錄的宏;

例如:

record_t record; 

    prase_t parse[] = 
    { 
     ROW("TEST", record, test, TYPE_STRING); 
     ROW("ID", record, id, TYPE_INT); 
    } 

與ROW執行以下操作:

  • 根據上式設置名稱值
  • ,如果它是TYPE_STRING,使用record.<variable>作爲變量,否則使用&(record.id)
  • 設置類型值
  • 將_b添加到傳遞給宏的變量名稱中並在行中使用它。

我試過很多選項和最接近的是以下

#define ROW(x, y, z, v) {x, (TYPE_STRING == v) ? y.z:&(y.z), v, &(y.z##_b)} 

但我使用它像以下

 The ":" operator is not allowed between "char[4]" and "char(*)[4]". 

我感謝所有幫助得到錯誤。我想我總是可以使用兩個不同的宏,一個用於字符串類型,另一個用於int,但我試圖儘可能簡化它。

+0

在宏擴展(C程序編譯器的第一步)期間,只有一個替換被創建,除了常量的藝術計算計算外,沒有評估。因此(TYPE_STRING == v)?將不會被評估,它會被放入你的結構併產生非法的C代碼。嘗試使用gcc的-E標誌來查看宏擴展的結果。 –

+0

嗨@SioulSeuguh,謝謝,但我沒有真正控制編譯器,我只能在代碼中更改 – wassim

+0

由於上一條語句是'但我試圖儘可能簡化它'。我建議(爲了簡單和可讀性)只需定義兩個結構體,並用宏包圍它們以在編譯時公開要使用的結構體。任何人都必須維護你的代碼,這會更易讀:) – ryyker

回答

1

爲什麼你需要TYPE_STRING測試?如果你只是將它轉換爲一個void *,那麼取一個數組的地址是一個noop,因爲在這種情況下數組將衰減到一個指針。因此,只需使用

#define ROW(x,y,z,v) { x, &(y.z), v, &(y.z##_b) }