4

在 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”的大小而创建一个虚拟变量。我认为有一种巧妙的方法可以将 0 重铸为 myStruct_t 以帮助查找成员变量“x”的大小,但它已经足够长,以至于我已经忘记了细节,并且似乎无法在这方面得到很好的谷歌搜索. 你知道吗?

谢谢!

4

6 回答 6

18

在 C++ 中(这是标签所说的),您的“虚拟变量”代码可以替换为:

sizeof myStruct_t().x;

不会创建 myStruct_t 对象:编译器只计算 sizeof 操作数的静态类型,它不执行表达式。

这在 C 中有效,在 C++ 中更好,因为它也适用于没有可访问的无参数构造函数的类:

sizeof ((myStruct_t *)0)->x
于 2009-09-09T16:22:01.573 回答
11

我正在使用以下宏:

#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 视为指向您的结构的指针。这是在编译时解决的,所以它是安全的。

于 2009-09-09T16:27:04.473 回答
3

你可以轻松做到

sizeof(myStruct().x)

由于永远不会执行 sizeof 参数,因此您不会真正创建该对象。

于 2009-09-09T16:22:38.623 回答
3

这些中的任何一个都应该起作用:

sizeof(myStruct_t().x;);

或者

myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)

或者

sizeof(((myStruct_t *)NULL)->x);

因为sizeof是在编译时而不是运行时评估的,所以取消引用 NULL 指针不会有问题。

于 2009-09-09T16:26:12.760 回答
2

在 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);
于 2012-08-29T14:04:00.087 回答
0

从我的实用程序宏标题中:

#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

像这样调用:

FIELD_SIZE(myStruct_t, x);  
于 2009-09-09T18:05:58.313 回答