C中的单个结构成员的sizeof

时间:2010-08-24 03:06:36

标签: c struct sizeof

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

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

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

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

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 ;

是否可以在不使用child_t的情况下声明dummy

9 个答案:

答案 0 :(得分:171)

虽然使用#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)甚至被允许作为常量表达式。很酷的东西。

答案 1 :(得分:27)

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

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

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

<小时/> 编辑:我喜欢使用此技术的joey建议的member_size宏,我想我会使用它。

答案 2 :(得分:9)

使用预处理程序指令,即#define:

#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 ;

答案 3 :(得分:7)

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

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

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

答案 4 :(得分:4)

您可以将预处理程序指令用作size:

#define TEXT_MAX_SIZE 255

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

答案 5 :(得分:4)

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

typedef char description[255];

然后有一个字段

description text;

两种类型。

答案 6 :(得分:4)

c ++解决方案:

sizeof(Type :: member)似乎也在起作用:

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

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

答案 7 :(得分:4)

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机器上试过它并没有用;有用的。

答案 8 :(得分:0)

@ joey-adams,谢谢! 我正在搜索相同的东西,但是对于非char数组,它甚至可以这样工作:

#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,这也很好用:

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