我创建了以下结构:
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 },
};
字符串
但是,当我使用clang选项-Weverything
进行编译时,出现了以下警告:
warning: padding struct 'struct s_fct_printf' with 7 bytes to
align 'fct' [-Wpadded]
型
我找到了以下解决方案:
typedef struct s_fct_printf
{
char flag;
void (*fct)(void*);
char pad[7];
} t_fct_printf;
型
但这并不能解决问题:
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]
型
所以我试着说:
typedef struct s_fct_printf
{
char flag;
char pad[7];
void (*fct)(void*);
} t_fct_printf;
型
但得到了以下错误:
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 },
型
我找到的最后一个解决方案是,但我读到它没有优化,因为编译器不再打包我的变量。
typedef struct __atribute__((__packed__)) s_fct_printf
{
char flag;
void (*fct)(void*);
} t_fct_printf;
型
有没有好的解决办法?
3条答案
按热度按时间jogvjijk1#
我对你的问题给予了应有的考虑。我不认为添加填充字段是解决方案。它会破坏代码并引入潜在的未来问题。
我还理解一个质量要求,即所有代码都应该在没有警告或错误的情况下编译。但是,此警告仅提供信息,并不指出可能的错误。
我的建议是,在警告发生的地方和接受警告的地方,明确地抑制它。我建议(以VC为例):
字符串
我希望你的编译器有一个类似的机制。
mkh04yzy2#
字符串
有利于解决填充问题。但是,您必须更改初始化数组的方式。
使用方式
型
否则,编译器会尝试用
my_putstr_printf
初始化成员pad
,这不是您想要的。更新
您可以使用以下命令来避免大小为
pad
的硬编码数字7
:型
感谢@WeatherVane的建议。
bnl4lu3b3#
您似乎运行在64位系统上。
char
占用一个字节,编译器希望函数指针从64位(8字节)边界开始。因此,它需要在char
之后填充7个字节以对齐函数指针。编译器只会通知您这一点(由于隐含的选项
-Wpadded
),但代码不包含错误。