2014-06-05 36 views
1

當前運行時實現如下:編譯時檢查一個成員是否是最後一個類數據成員的任何方法?

#define ASSERT_LAST_Member(Class, Member) {Class foo; assert(((size_t)(&foo) + sizeof(foo)) == ((size_t)(&foo.Member) + sizeof(foo.Member)));} 

我該怎麼辦靜態斷言在編譯時?我試圖做到這一點,但沒有奏效。

#define assert_static(e) \ 
    do { \ 
     enum { assert_static__ = 1/(e) }; \ 
     } while (0) 
#define ASSERT_LAST_Member(Class, Member) { assert_static(((size_t)&((Class*)0)->Member)+sizeof(((Class*)0)->Member)==sizeof(Class)) } 
+3

斷言數據成員是最後一個是代碼味道。設計有問題。你有沒有機會嘗試在結構的末尾放置一個動態大小的數組? –

+0

說「不起作用」是模糊的。請參閱http://stackoverflow.com/questions/how-to-ask。 – jarmod

+0

如果我在這個類中添加了另一個成員(例如協議),並且有許多地方可以對新成員進行操作,ASSERT_LAST_Member可以確保沒有錯過任何東西。 – pixar

回答

1

你不能真正斷言成員今天是最後一個班。針對N3814的建議可能會使這一點成爲可能,一旦被接受和實施,但它們目前無法使用。使用目前可用的內容,由於填充問題,您仍然陷入困境(請參閱Csq在評論中的示例)。

如果您忽略填充的侷限性,並將自己限制爲沒有虛擬繼承的「普通舊數據」情況,則可以使用offsetof macroHow to calculate offset of a class member at compile time?的建議來執行所需的檢查。

但實際上,根據您對所有類爲協議類的評論,您是否可以不對已知的類大小進行斷言?它不會在成員重新排序或者在添加內容的時候捕捉到案例。但靜態斷言實際上只是爲了防止意外的錯誤更改,並聲稱不使用填充。所以去簡單:

static_assert(sizeof(Foo) == 12, "Size of Foo has changed"); 
相關問題