C++ 为什么';解析结构成员的大小?

C++ 为什么';解析结构成员的大小?,c++,sizeof,C++,Sizeof,我知道sizeof是一个编译时计算,但这对我来说似乎很奇怪:编译器可以采用类型名,也可以采用表达式(从中推断类型)。但是如何识别类中的类型呢?似乎唯一的方法是传递一个表达式,它看起来相当笨拙 struct X { int x; }; int main() { // return sizeof(X::x); // doesn't work return sizeof(X()::x); // works, and requires X to be default-constructi

我知道
sizeof
是一个编译时计算,但这对我来说似乎很奇怪:编译器可以采用类型名,也可以采用表达式(从中推断类型)。但是如何识别类中的类型呢?似乎唯一的方法是传递一个表达式,它看起来相当笨拙

struct X { int x; };
int main() {
    // return sizeof(X::x); // doesn't work
    return sizeof(X()::x); // works, and requires X to be default-constructible
}

替代方法不需要默认构造函数即可工作:

return sizeof(((X *)0)->x);
您可以将其包装在宏中,以便更好地阅读:

#define member_sizeof(T,F) sizeof(((T *)0)->F)

那么的偏移量呢?看一看。还可以查看一下,它将
sizeof
offsetof
组合到一个宏中


希望这能有所帮助。

这是一个没有讨厌的空指针解引用的解决方案;)

结构X{int X;}; 模板T make();//请注意,这只是一个声明 int main() {
std::cout对
sizeof(X::X)
的支持包含在C++0x(cf.)中。@James+1在您的评论中。我的回答(已删除)实际上应该是一条评论,因为Tom没有提到C++0x。也许他想在C++98中使用它:)是的,我的问题是关于C++98的。然而,即使我使用
-std=C++0x
构建,它也不起作用(GCC 4.3.2)有没有编译器支持实现它?英特尔C++编译器11.1不支持它。GCC 4.4包括对它的支持(PER;我没有安装GCC来测试它)。AFEK,取消空指针是不确定的行为。这个规则也适用于这种情况吗?@阿拉克:我不这么认为:“Ssieof的操作数”要么是一个未计算的表达式,要么是一个带括号的类型id”(5.3.3/1;emphasis mine)。空指针永远不会被取消引用。这是一个编译时操作。只是为了让编译器做正确的事情(tm)。这不是“return sizeof…”与offsetof相同吗?@tommieb75:sizeof
x
x
成员占用的字节数。offsetof
x
x
从其封闭结构
x
开始偏移的字节数。这没有帮助,因为编译器(虽然需要按照声明的顺序对结构的元素进行排序)可以在它认为必要时自由填充它们。您不能说
extern t fakeT;sizeof(fakeT.x);
struct X { int x; };

template<class T> T make(); // note it's only a declaration

int main()
{
    std::cout << sizeof(make<X>().x) << std::endl;
}