Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof single struct member in C

Tags:

c

struct

sizeof

Although defining the buffer size with a #define is one idiomatic way to do it, another would be to use a macro like this:

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

and use it like this:

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

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

I'm actually a bit surprised that sizeof((type *)0)->member) is even allowed as a constant expression. Cool stuff.


I am not on my development machine right now, but I think you can do one of the following:

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

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


Edit: I like the member_size macro Joey suggested using this technique, I think I would use that.

You are free to use FIELD_SIZEOF(t, f) in the Linux kernel. It's just defined as following:

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

This type of macro is mentioned in other answers. But it's more portable to use an already-defined macro.


Use a preprocessor directive, i.e. #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 ;

struct.h has them already defined,

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

so you could,

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

but, on looking in the header, it appears that this is a BSD thing and not ANSI or POSIX standard. I tried it on a Linux machine and it didn't work; limited usefulness.