C中的单个结构成员的sizeof

sizeof single struct member in C

我试图声明依赖于另一个结构的结构。我想用sizeof来保证安全/学究。

1
2
3
4
5
6
typedef struct _parent
{
  float calc ;
  char text[255] ;
  int used ;
} parent_t ;

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

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

1
2
3
4
5
6
typedef struct _child
{
  char flag ;
  char text[sizeof(parent_t.text)] ;
  int used ;
} child_t ;

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

作为一个技巧,这似乎有效:

1
2
3
4
5
6
7
parent_t* dummy ;
typedef struct _child
{
  char flag ;
  char text[sizeof(dummy->text)] ;
  int used ;
} child_t ;

在不使用dummy的情况下,是否可以申报child_t


虽然用#define定义缓冲区大小是一种惯用方法,但另一种方法是使用如下宏:

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

像这样使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
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)作为一个常量表达式。很酷的东西。


我现在不在开发机器上,但我认为您可以执行以下操作之一:

1
2
3
sizeof(((parent_t *)0)->text)

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


编辑:我喜欢乔伊建议使用的成员尺寸宏,我想我会使用它。


使用预处理器指令,即定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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 ;


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

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

这种类型的宏在其他答案中提到。但使用已经定义的宏更容易移植。


struct.h已经定义了,

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

所以你可以,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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 *.
"
,
           name_size, child_size);
    return EXIT_SUCCESS;
}

但是,在查看头部时,似乎这是一个BSD东西,而不是ANSI或POSIX标准。我在一台Linux机器上尝试过,但没有成功;实用性有限。


C++解决方案:

sizeof(type::member)似乎也在工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Parent
{
    float calc;
    char text[255];
    int used;
};

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


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

1
typedef char description[255];

然后有一块地

1
description text;

在这两种类型中。


可以将预处理器指令的大小用作:

1
#define TEXT_MAX_SIZE 255

在父级和子级中都使用它。


@乔伊·亚当斯,谢谢你!我搜索的是相同的东西,但对于非char数组,即使这样也可以很好地工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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。

而且,@brandon horsley,这也很有效:

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