可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
?
回答1:
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.
回答2:
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.
回答3:
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 ;
回答4:
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.
回答5:
You can use a preprocessor directive for size as:
#define TEXT_MAX_SIZE 255
and use it in both parent and child.
回答6:
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.
回答7:
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.
回答8:
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;
};
回答9:
@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])