sizeof single struct member in C

CStructSizeof

C Problem Overview


I am trying to declare a struct that is dependent upon another struct. I want to use sizeof to be safe/pedantic.

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

Now I want to declare a struct child_t that has the same size as parent_t.text.

How can I do this? (Pseudo-code below.)

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

I tried a few different ways with parent_t and struct _parent, but my compiler will not accept.

As a trick, this seems to work:

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

Is it possible to declare child_t without the use of dummy?

C Solutions


Solution 1 - C

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.

Solution 2 - C

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.

Solution 3 - C

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.

Solution 4 - C

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 ;

Solution 5 - C

You can use a preprocessor directive for size as:

#define TEXT_MAX_SIZE 255

and use it in both parent and child.

Solution 6 - C

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.

Solution 7 - C

Another possibility would be to define a type. The fact that you want to ensure the same size for the two fields is an indicator that you have the same semantics for them, I think.

typedef char description[255];

and then have a field

description text;

in both of your types.

Solution 8 - C

c++ solution:

sizeof(Type::member) seems to be working as well:

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

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

Solution 9 - C

@joey-adams, thank you! I was searching the same thing, but for non char array and it works perfectly fine even this way:

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

It returns 20 as expected.

And, @brandon-horsley, this works good too:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkevinarpeView Question on Stackoverflow
Solution 1 - CJoey AdamsView Answer on Stackoverflow
Solution 2 - CBrandon HorsleyView Answer on Stackoverflow
Solution 3 - CDmitryView Answer on Stackoverflow
Solution 4 - Cdave mankoffView Answer on Stackoverflow
Solution 5 - CcodaddictView Answer on Stackoverflow
Solution 6 - CNeilView Answer on Stackoverflow
Solution 7 - CJens GustedtView Answer on Stackoverflow
Solution 8 - CkorishView Answer on Stackoverflow
Solution 9 - CRoman KovtuhView Answer on Stackoverflow