C中的单个结构成员的sizeof

kev*_*rpe 101 c struct sizeof

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

typedef struct _parent
{
  float calc ;
  char text[255] ;
  int used ;
} parent_t ;
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能做到这一点?(下面的伪代码.)

typedef struct _child
{
  char flag ;
  char text[sizeof(parent_t.text)] ;
  int used ;
} child_t ;
Run Code Online (Sandbox Code Playgroud)

我试着用几种不同的方法parent_tstruct _parent,但我的编译器不接受.

作为一个技巧,这似乎工作:

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

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

Joe*_*ams 185

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

#define member_size(type, member) sizeof(((type *)0)->member)
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

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

typedef struct
{
    char flag;
    char text[member_size(Parent, text)];
    int used;
} Child;
Run Code Online (Sandbox Code Playgroud)

我实际上有点惊讶sizeof((type *)0)->member)甚至被允许作为一个常量表达式.酷的东西.

  • @gordongekko:谢谢.仍然是一个宝石,对我来说很棒. (5认同)
  • 精彩?它的简单C89,请参见<stddef.h>中的"offsetof"实现或相同的实现http://www.eetimes.com/design/other/4024941/Learn-a-new-trick-with-the-offsetof- -macro (4认同)
  • @Gangadhar:是的,这适用于所有编译器。不评估`sizeof`的操作数,因此取消引用空指针没有问题(因为它实际上并未被取消引用)。 (3认同)
  • [Wikipedia page for offset_of](https://en.wikipedia.org/wiki/Offsetof) 指出这是根据 C 标准的未定义行为,所以我不会打赌它适用于所有编译器。 (3认同)
  • 哇,我不知道 sizeof((type *)0)-&gt;member) 工作。现在不在我的开发机器上,但这对所有编译器都有效吗?谢谢你的乔伊。 (2认同)

Bra*_*ley 28

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

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

sizeof(((parent_t){0}).text)
Run Code Online (Sandbox Code Playgroud)


编辑:我喜欢member_size宏,Joey建议使用这种技术,我想我会用它.

  • 第二种形式非常好(并且在概念上是干净的,因为它不涉及空指针),但你应该提到它在C99之前的编译器中是不可能的. (9认同)
  • @PunyCode - `sizeof` 操作数在编译时评估,因此没有内存问题。 (4认同)

dav*_*off 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 ;
Run Code Online (Sandbox Code Playgroud)

  • 我不认为你理解我。假设父结构为`drand48_data`(在stdlib.h中定义),并且您想要的大小为`__x`。您无法`#define X_LEN 3`并更改stdlib.h,当您无法访问父结构的源代码时,使用`member_size`是更好的选择,这似乎是合理的情况。 (2认同)

小智 7

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

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
Run Code Online (Sandbox Code Playgroud)

其他答案中提到了这种类型的宏.但是使用已经定义的宏更加便携.

  • 它最近被从 linux/kernel.h 中[删除](https://github.com/torvalds/linux/commit/1f07dcc459d5f2c639f185f6e94829a0c79f2b4c)。 (5认同)
  • FIELD_SIZEOF是现代Linux内核中使用的宏,可以在linux/kernel.h中找到 (4认同)
  • @AndriyMakukha 我也遇到了这个问题......它现在被称为“sizeof_field”(“&lt;linux/stddef.h&gt;”),没有任何净变化,只是重命名。 (4认同)

cod*_*ict 5

您可以将预处理器指令用于大小:

#define TEXT_MAX_SIZE 255
Run Code Online (Sandbox Code Playgroud)

并在父母和孩子中使用它。


Jen*_*edt 5

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

typedef char description[255];
Run Code Online (Sandbox Code Playgroud)

然后有一个字段

description text;
Run Code Online (Sandbox Code Playgroud)

在你的两种类型中。


kor*_*ish 5

C++解决方案:

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

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

struct Child
{
    char flag;
    char text[sizeof(Parent::text)];
    int used;
};
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于 C,而不是 C++。 (4认同)

Nei*_*eil 5

struct.h 他们已经定义了,

#define fldsiz(name, field) \
    (sizeof(((struct name *)0)->field))
Run Code Online (Sandbox Code Playgroud)

这样你就可以

#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;
}
Run Code Online (Sandbox Code Playgroud)

但是,在查看标题时,这似乎是 BSD 的东西,而不是 ANSI 或 POSIX 标准。我在 Linux 机器上试过了,没有用;用处有限。