单结构构件的尺寸

我试图声明一个依赖于另一个结构的结构。 我想使用 sizeof是安全/迂腐。

typedef struct _parent
{
float calc ;
char text[255] ;
int used ;
} parent_t ;

现在我要声明一个大小与 parent_t.text相同的结构 child_t

我该怎么做? (下面是伪代码)

typedef struct _child
{
char flag ;
char text[sizeof(parent_t.text)] ;
int used ;
} child_t ;

我尝试了几种不同的方法与 parent_tstruct _parent,但我的编译器不会接受。

作为一种把戏,这似乎奏效了:

parent_t* dummy ;
typedef struct _child
{
char flag ;
char text[sizeof(dummy->text)] ;
int used ;
} child_t ;

是否可以不使用 dummy声明 child_t

78572 次浏览

使用预处理器指令,例如 # Definition:

#define TEXT_LEN 255


typedef struct _parent
{
float calc ;
char text[TEXT_LEN] ;
int used ;
} parent_t ;


typedef struct _child
{
char flag ;
char text[TEXT_LEN] ;
int used ;
} child_t ;

可以使用预处理器指令来确定大小:

#define TEXT_MAX_SIZE 255

并在父母和孩子身上使用。

我现在不在我的开发机器上,但我认为你可以做以下任何一个:

sizeof(((parent_t *)0)->text)


sizeof(((parent_t){0}).text)


编辑 : 我喜欢成员大小宏 Joey 建议使用这种技术,我想我会使用它。

虽然用 #define定义缓冲区大小是一种惯用的方法,但是另一种方法是使用类似下面这样的宏:

#define member_size(type, member) sizeof(((type *)0)->member)

像这样使用它:

typedef struct
{
float calc;
char text[255];
int used;
} Parent;


typedef struct
{
char flag;
char text[member_size(Parent, text)];
int used;
} Child;

实际上,我有点惊讶于 sizeof(((type *)0)->member)竟然被允许作为一个常量表达式。

另一种可能性是定义一个类型。我认为,您希望确保这两个字段的大小相同,这表明您对它们具有相同的语义。

typedef char description[255];

然后有一块地

description text;

你们两个都是。

C + + 解决方案:

Sizeof (Type: : member)似乎也在工作:

struct Parent
{
float calc;
char text[255];
int used;
};


struct Child
{
char flag;
char text[sizeof(Parent::text)];
int used;
};

struct.h已经定义了它们,

#define fldsiz(name, field) \
(sizeof(((struct name *)0)->field))

这样你就可以,

#include <stdlib.h> /* EXIT_SUCCESS */
#include <stdio.h>  /* printf */
#include <struct.h> /* fldsiz */


struct Penguin {
char name[128];
struct Penguin *child[16];
};
static const int name_size  = fldsiz(Penguin, name) / sizeof(char);
static const int child_size = fldsiz(Penguin, child) / sizeof(struct Penguin *);


int main(void) {
printf("Penguin.name is %d chars and Penguin.child is %d Penguin *.\n",
name_size, child_size);
return EXIT_SUCCESS;
}

但是,在头部查看,这似乎是一个 BSD 的东西,而不是 ANSI 或 POSIX 标准。我在一台 Linux 机器上尝试过,但它不起作用; 用处有限。

您可以在 Linux 内核中自由地使用 FIELD_SIZEOF(t, f)。 它的定义如下:

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

这种类型的宏在其他答案中也有提到,但是使用已经定义的宏更具可移植性。

@ Joey-Adams 谢谢! 我也在搜索同样的东西,但是对于非字符数组,即使这样它也能很好地工作:

#define member_dim(type, member) sizeof(((type*)0)->member) / \
sizeof(((type*)0)->member[0])


struct parent {
int array[20];
};


struct child {
int array[member_dim(struct parent, array)];
};


int main ( void ) {
return member_dim(struct child, array);
}

如预期返回20。

而且,“布兰登-霍斯利,这也很有效:

#define member_dim(type, member) sizeof(((type){0}).member) / \
sizeof(((type){0}).member[0])