構造体メンバーのサイズを決定する一般的なC / C ++マクロとは何ですか?
質問
C / C ++では、その構造タイプのダミー変数を定義する必要なく、構造に対するメンバー変数のサイズをどのように決定しますか?間違った方法の例を次に示しますが、意図を示しています。
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x); // error
参考として、ダミー変数を最初に定義する場合、これは 'x'のサイズを見つける方法でなければなりません:
myStruct_t dummyStructVar;
const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);
ただし、「x」のサイズを取得するためだけにダミー変数を作成する必要がないようにしたいと考えています。メンバー変数「x」のサイズを見つけるのに役立つmyStruct_tとして0をリキャストする賢い方法があると思いますが、詳細を忘れてしまったので、これで適切なGoogle検索を取得できないようです。知っていますか
ありがとう!
解決
C ++(タグの意味)では、「ダミー変数」コードは次のように置き換えることができます:
sizeof myStruct_t().x;
myStruct_tオブジェクトは作成されません。コンパイラは、静的タイプのsizeofのオペランドのみを処理し、式は実行しません。
これはCで機能します。C++では、引数なしのアクセス可能なコンストラクタがないクラスでも機能するため、より優れています。
sizeof ((myStruct_t *)0)->x
他のヒント
次のマクロを使用しています:
#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
struct ABC
{
int a;
char b;
double c;
};
std::cout << "ABC::a=" << DIM_FIELD(ABC, a)
<< " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;
return 0;
}
Trickは0を構造体へのポインタとして扱っています。これはコンパイル時に解決されるため、安全です。
簡単にできます
sizeof(myStruct().x)
sizeofパラメーターは実行されないため、実際にはそのオブジェクトを作成しません。
これらのいずれも機能するはずです:
sizeof(myStruct_t().x;);
または
myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)
または
sizeof(((myStruct_t *)NULL)->x);
sizeof
は実行時ではなくコンパイル時に評価されるため、NULLポインターの逆参照に問題はありません。
C ++ 11では、これは sizeof(myStruct_t :: x)
で実行できます。 C ++ 11では、 std :: declval も追加され、これに使用できます。 (特に):
#include <utility>
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);
ユーティリティマクロヘッダーから:
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
次のように呼び出されました:
FIELD_SIZE(myStruct_t, x);