Xwilarg Xwilarg - 16 days ago 10
C Question

Warning for struct padding in Clang

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 -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?

Answer
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.

Comments