簡體   English   中英

在C中類型轉換更大或更小的結構

[英]typecasting bigger or smaller structure in C

我在C程序中有兩個結構:SmallStructABC和BigStructXYZ

我倆都有幾個成員。 SmallStructABC的所有10個成員與BigStructXYZ的前10個成員完全相同。 BigStructXYZ還有50個其他成員。

可以將這兩個結構彼此類型轉換嗎?

SmallStructABC *i = (BigStructXYZ*)j;
BigStructXYZ   *a = (SmallStructABC*)b; 

類型轉換后,我只能訪問前10個(普通)成員。

我編寫了C程序,並在我的機器上正常工作。 只是想確認我是否需要處理所有極端情況(對齊,無效讀取,非gcc編譯等)。

編輯:問:為什么我想做這樣的事情?

答:BigStructXYZ的大小非常大(例如50KB),並且包含一些標頭(鍵,映射等)。 我先壓縮這些數據,然后再通過網絡發送。 我保留標頭(在我們的示例中為SmallStructABC)。 通過類型轉換,可以在需要時從標題訪問這些鍵。

不,這不是一個好主意。 更好的方法是將類型轉換指針鍵入結構並通過指針對其進行操作:

void DoSomething(Small *thing) {
    // ...
}

int main() {
    Big big = {0};
    Small small = {0};

    Small *p0 = (Small*)&big;
    Small *p1 = &small;

    DoSomething(p0);
    DoSomething(p1);

    return 0;
}

另一種更安全的設計是用Small來定義Big

typedef struct Small {
    int foo;
};
typedef struct Big {
    Small small;
    int y;
};

上面的代碼無法編譯。 j已經是BigStructXYZ,並且您是要將其強制轉換為SmallStructABC嗎?

無論如何,您要嘗試做的都是一個壞主意。 最好將SmallStructXYZ作為BigStructXYZ內的第一個字段並按以下方式工作:

SmallStructABC i = j.smallStruct;
BigStructXYZ a = { b };

我可以想到無法保證無法解決這些問題的情況,但是在大多數情況下,在大多數平台上都可以。 我想到的是對齊應該由結構的最大成員決定,因此,如果較大結構中有64位成員或其他內容,則可能會影響對齊前幾個成員。 很抱歉,我目前沒有更可靠的消息來源或更清晰的解釋。

在我自己的代碼中,我希望將標頭直接嵌入到較大的結構中,如Frank Kreuger的答案中所述,並使用bigStruct.header.someMember類型的接口來避免任何類型的轉換和對齊困難。

是的,你可以做到。 SmallStructABC在內存中的位置將與BigStructXYZ的第一部分完全相同。

我將此與工會一起使用。 系統接收有效負載,它可能是標頭或標頭+數據。

我這樣寫聯合:

union HeaderOrHeaderData
{
    SmallStructABC header;
    BigStructXYZ headerData;
};

HeaderOrHeaderData* ptr = (HeaderOrHeaderData*) data_ptr;

這種方法比直接強制轉換的優勢在於,可能會(錯誤地)錯誤結構的指針(實際上指向小結構)並在指向大結構時使用它。

如果您始終使用工會,您將三思。

我嘗試了幾種編譯器,操作系統和平台形式的解決方案。 它在任何時候都可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM