2010-12-20 96 views
2

我想將一些舊代碼從20年前的DOS系統移植到GNU Linux系統。在他們的幾個頭文件中(這些頭文件都包含在這個地方),它們具有他們聲明和初始化的結構體的結構。我在編寫遺留代碼的方式編譯時收到警告。關於如何讓這個工作保持在同一個頭文件中的任何提示?如何在C頭文件中初始化一個struct結構體?

以下是我所做的一個簡化的例子。

struct A 
{ 

    struct B temp1; 
    struct C temp2; 
}; 

struct B 
{ 

    int temp3; 
    int temp4; 
    int temp5; 
}; 

struct C 
{ 

    int temp6; 
    int temp7; 
    int temp8; 
}; 


//These are the variables in how they are related to the initialization below 

//struct A test_one = {{temp3,temp4,temp5},{temp6,temp7,temp8}}; 

struct A test_one = {{1,2,3},{4,5,6}}; 
+2

什麼是警告? – OrangeDog 2010-12-20 15:19:18

回答

1

申報結構B和A之前C,即:

struct B { int temp3; int temp4; int temp5; }; 
struct C { int temp6; int temp7; int temp8; }; 
struct A { struct B temp1; struct C temp2; }; 
+0

我的不好,我只是一個簡單的例子。在實際代碼中,「結構A」在B和C之後聲明。 – user548800 2010-12-20 15:43:00

6

不應實例化的任何結構中的頭文件。如果你做了一個不同的實例,將會在每個C文件中創建一個頭文件,其中通常不包含所需的效果。

在一個C文件中,你需要執行以下操作。

void foo(){ 
struct A parent; 
struct B child_b; 
struct C child_c; 

child_b.temp3 = 3; 
child_b.temp4 = 4; 
child_b.temp5 = 5; 

child_c.temp6 = 6; 
child_c.temp7 = 7; 
child_c.temp8 = 8; 

parent.temp1 = child_b; 
parent.temp2 = child_c; 
} 

我會強烈考慮制定類似這樣

void initB(struct B* s, int x, int y, int z){ 
    s->temp3 = x; 
    s->temp4 = y; 
    s->temp5 = z; 
} 

輔助功能如果您希望保留則數組初始化語法可以考慮使用一個工會。

+0

特別是因爲它們沒有被聲明爲靜態的。我知道有些人幾年前做了類似的事情,而不是抱怨,因爲每次引用多重定義的變量時,鏈接器似乎都隨機使用其中一個實例。 – JeremyP 2010-12-20 15:28:08

+0

@JeremyP:你必須在頭文件中聲明變量'extern'並且在一個編譯單元中實例化和初始化它。 – 2010-12-20 15:49:02

+0

我真的試過在C文件裏面做同樣的事情而不是頭文件,我得到了相同的警告。我想我應該將原來的問題重新定義爲「如何初始化C中一個struct結構體?」。我得到的警告是「初始化程序附近缺失的括號」警告以及「近似初始化...」警告。 – user548800 2010-12-20 15:55:25

0

您發佈的代碼不可編譯,因爲使用不完整類型聲明struct成員是非法的。我假設你只是錯誤地排列了你的struct定義:BC應該先定義。

話雖如此,此代碼可以生成的唯一警告是來自鏈接器的「警告」,如果頭文件包含在多個翻譯單元中,它可能會抱怨同一對象test_one的多個定義。在C中,這在技術上是非法的,雖然許多編譯器允許它作爲流行的編譯器擴展。

那麼,你會得到什麼「警告」?

+0

我得到一個「初始化程序周圍的缺失括號」警告以及「接近初始化...」的警告。 – user548800 2010-12-20 15:45:11