2011-09-05 84 views
2

我希望我可以使用预处理器,但输入来自运行时..我尝试了条件typedef,不起作用。或有条件的声明,不起作用。虽然我并没有真正期望他们没有。而且,因为所有跟随的代码都完全相同,所以我不希望为每个结构重写两次。2结构之间的兼容性

有没有办法在C中做到这一点?或者采用不同的方法,结果相同。我所有的谷歌搜索都将我带入了C++模板。如果我不清楚,也许这将有所帮助:

#include <stdio.h> 

struct a32 { 
    short bits; 
    unsigned long val; 
    // more values, not necessarily in the same order 
}; 

struct a64 { 
    short bits; 
    unsigned long long val; 
    // etc... 
}; 

int main(void) { 
    struct a32 mystruct; 

    // read mystruct from somewhere 

    if(mystruct.bits == 64) { 
     // then I need mystruct to be a64 
     // re-read mystruct 
    } 

    // exact same code for both structs 

    printf("%d\n", sizeof(mystruct.val)); 
    return 0; 
} 

任何帮助,将不胜感激。

回答

3

为什么不这样做,假设填充不会是一个问题:

struct { 
    unsigned long val; 
} a32; 

struct { 
    unsigned long long val; 
} a64; 

int main(void) { 
    short bits; 
    union { 
     struct a32 struct32; 
     struct a64 struct64; 
    }; 

    // Read bits 

    if (bits == 64) { 
     // Read into struct64 
    } else { 
     // Read into struct32 
    } 

    return 0; 
} 

这当然会,要求你要知道的bits值的,所以你知道哪些结构体变量访问。

2

可以“八九不离十”做到这一点使用工会:

struct{ 
    short bits; 
    union{ 
     unsigned long a32; 
     unsigned long long a64; 
    }; 
} a_int; 

int main(void) { 
    a_int mystruct; 

    // read mystruct from somewhere 

    if(mystruct.bits == 64) { 
     // then I need mystruct to be a64 
     // re-read mystruct 
    } 

    // exact same code for both structs 

    printf("%d\n", sizeof(mystruct.a32)); 
    return 0; 
} 

编辑: 然而,它不可能使printf()工作在32位和64位整数。

+0

这应该是我的解决方案:)我认为不应该有填充问题,因为联盟将至少与其中声明的最大类型一样大? – Dan

+0

谢谢,我认为这将做到这一点。 – olly

+2

读完整的结构是一个坏主意。您需要先读取“位”,然后对该值进行“切换”以填充其余数据。 – James

1

不是100%肯定这是你的意思。如果没有,请澄清这个问题。

您应该使用带标签的联合。用一个标记(例如一个int)和一个联合来创建一个结构体。该联盟位于可能存在的可能结构之间,并且该标签可以确定它是哪一个结构。

谷歌“标记联盟”的更多细节。