I created the following structure:
typedef struct s_fct_printf
{
char flag;
void (*fct)(void*);
} t_fct_printf;
static const t_fct_printf flags[] =
{
{ 's', my_putstr_printf },
//[...]
{ 'b', display_base_2 },
};
But when I compile with clang option -Weverything
, I have the following warning:
warning: padding struct 'struct s_fct_printf' with 7 bytes to
align 'fct' [-Wpadded]
I found the following solution :
typedef struct s_fct_printf
{
char flag;
void (*fct)(void*);
char pad[7];
} t_fct_printf;
But it's not solving the problem:
warning: missing field 'pad' initializer [-Wmissing-field-initializers]
{ 'b', display_base_2 },
warning: padding struct 'struct s_fct_printf' with 7 bytes to
align 'fct' [-Wpadded]
So I tried that:
typedef struct s_fct_printf
{
char flag;
char pad[7];
void (*fct)(void*);
} t_fct_printf;
But got the following errors:
warning: incompatible pointer to integer conversion initializing 'char'
with an expression of type 'void (void *)' [-Wint-conversion]
{ 'b', display_base_2 },
warning: suggest braces around initialization of subobject
[-Wmissing-braces]
{ 'b', display_base_2 },
warning: missing field 'fct' initializer [-Wmissing-field-initializers]
{ 'b', display_base_2 },
error: initializer element is not a compile-time constant
{ 's', my_putstr_printf },
The last solution I found was that, but I have read it's not optimized since the compilator does not packaging my variables anymore.
typedef struct __atribute__((__packed__)) s_fct_printf
{
char flag;
void (*fct)(void*);
} t_fct_printf;
Is there a good solution?
typedef struct s_fct_printf
{
char flag;
char pad[7];
void (*fct)(void*);
} t_fct_printf;
is good for taking care of the padding issue. However, you'll have to change the way you initialize the array.
Use
static const t_fct_printf flags[] =
{
{ 's', "", my_putstr_printf },
{ 'b', "", display_base_2 },
};
Otherwise, the compiler tries to initialize the member pad
with my_putstr_printf
, which is not what you want.
Update
You can avoid the hard coded number 7
for the size of pad
by using:
typedef struct s_fct_printf
{
char flag;
char pad[sizeof(void(*)(void))-1];
void (*fct)(void*);
} t_fct_printf;
Thanks are due to @WeatherVane for the suggestion.