2012-12-25 47 views
0

我無法猜測的使用結構,如使用構造struct {a [0]}測試;

struct 
{ 
    uint64_t offsets[0]; 
} table; 

請給我一些暗示關於這一點。

+0

這與以下情況有何不同:'struct {uint64_t offset; }表;' – Shraddha

+1

除了一些特定於實現的東西外,您現在沒有什麼實際用途。它類似於經典的「struct hack」,但是您提供的聲明不能用於此目的。 – AnT

+0

它的不同之處在於'uint64_t offset'會引入一個'uint64_t'類型的字段。同時,一個大小爲'0'的數組(如果它編譯在你的編譯器中)根本不會引入數據。你的變量'table'是空的。它本身的大小爲'0',這就是爲什麼我說它沒有實際用途。實際上,它唯一使用的就是在內存中佔用一些唯一的地址。 – AnT

回答

0

您已定義未命名的struct實際上table是對象不是struct的名稱。

所以,如果你有這樣的聲明

typedef struct 
{ 
    uint64_t offsets[0]; 
} table; 

或者,

struct table 
    { 
     uint64_t offsets[0]; 
    } table; 

然後,這就是所謂的可變長度數組(稱爲結構破解)。

有限制,它應該是結構的最後一個成員。

更多關於它see this article on struct hack

+2

這不是一個「struct hack」。 「結構黑客」將需要一個命名結構類型和動態內存分配。在上面的例子中,類型沒有被命名,變量'table'被立即聲明。 – AnT

+0

哦,是的,你是正確的......我認爲struct是typedef ..對不起,我的錯誤 – Omkant

+0

@amorenoc:形式上,這是非法的。所以,「略有不同」是輕描淡寫。但在允許它的編譯器中,語義與C99中的靈活數組成員相同,除非我錯過了某些東西。我是嗎? – AnT

5

您發佈的代碼是正式失效。正式的C語言不支持尺寸爲0的數組。

一些編譯器(使用鬆散/遺留錯誤檢查)允許在結構的結尾處有一個大小爲零的數組,它有時用於實現所謂的"struct hack"。 (更好的方法是使用大小爲1的尾部數組。)但是,您的聲明不提供該用途。 「Struct hack」需要一個命名的結構類型,而實際的對象必須動態分配。在你的情況下,結構類型是未命名的,變量table是非動態定義的。所以,「struct hack」在這裏是沒有問題的,假設你正確地重現了代碼。

因此,即使它編譯,最終變量table包含沒有可用的數據。該變量的唯一用途(如果聲明爲靜態存儲持續時間)是通過&table表達式(指向「匿名結構」類型的指針)產生唯一的地址常量。

一種方式把你的宣言到的東西更接近「結構黑客」是在它前面加上一個typedef

typedef struct 
{ 
    uint64_t offsets[0]; 
} table; 

然而,「人類產生的」結構聲明爲「結構黑客「通常會在靈活數組聲明之前包含其他數據字段(沒有它們就沒有必要在普通數組上選擇」struct hack「)。

+0

在Linux內核中,我們可以將問題縮小到GCC可以處理的問題。 – Potatoswatter

1

這是一種技巧,可以讓您將任意大小的內存塊轉換爲您的指針類型,並使最後一個數組成員變爲可變長度數組。雖然可能不是標準的,但這是可行的,因爲C數組不是邊界檢查的。

這裏是一個非常簡單的例子來展示它:

typedef struct Foo 
{ 
    int count; 
    int array[0]; 
} Foo; 

Foo* foo = (Foo*)malloc(sizeof(Foo) + 5 * sizeof(int)); 
foo->count = 5; 

然後,您可以使用count域得知該Foo*中有效元素的數量。如上所述,由於C數組未經過邊界檢查,因此編譯器和運行庫在您嘗試讀取或寫入數據時都不會捕獲大小爲0的大小爲foo->array

+0

OP的代碼使用了一個未命名的結構,並定義了該類型的變量「table」。您如何提出使用未命名的結構來達到您在答案中描述的目的?變量'table'的目的是什麼? (另外,這是C,這意味着在你的回答中你聲明'struct Foo'不只是'Foo')。 – AnT

+1

@AndreyT,不需要那麼激進。我假設OP的問題的「如」部分意味着這不是他發現的實際代碼,而是他發現的模式。 (此外,我只是鍵入我的結構,使其工作。) – zneak

+0

所以基本上這意味着'0'只是愚蠢的編譯器堅持的事實,當程序員需要在'[]結構 ? – Shraddha