C 中的通用函数 typedef - 如何摆脱初始化警告?
Generic function typedef in C - how to get rid of initialization warning?
我正在试验类似通用的代码,我有一个这样的函数(删除了很多不相关的代码):
typedef uint8_t (*struct_converter_t)(void *, char *);
void convert_struct(
struct_converter_t converter, // this is a function
const char * file_name
){
some_struct_t * some_struct;
converter(some_struct, some_string_buffer);
}
当我尝试分配一个接受 some_struct_t
(而不是 void *
)的函数时:
static uint8_t some_converter(some_struct_t * vd, char * s);
给我的 struct_converter_t
像这样:
struct_converter_t converter = some_converter; // WARNING HERE
我明白了:
initialization of 'struct_converter_t' {aka 'unsigned char (*)(void *, char *)'} from incompatible pointer type 'uint8_t (*)(some_struct_t *, char *)' {aka 'unsigned char (*)(struct <anonymous> *, char *)'} [-Wincompatible-pointer-types]
我对 C 没有经验,我想知道是否有办法优雅地摆脱这个警告。
您分配给函数指针类型的函数具有与函数指针不兼容的参数。
您的函数将 some_struct_t *
作为第一个参数,但函数指针类型将 void *
作为第一个参数。虽然任何对象指针都可以 to/from 转换为 void *
,但不会扩展到函数指针参数。
您需要更改您的函数,使其第一个参数采用 void *
以与函数指针兼容。然后在函数内部,您可以将 void *
参数转换为 some_struct_t *
.
在 C 中,您可以向需要 void*
的函数提供类型 X*
的参数。但就转换而言,仅此而已。您不能将第一个参数为 X*
的函数用作第一个参数为 void*
.
的函数的参数
原因是C不保证X*
和void*
表示相同。它确实保证编译器知道如何以不破坏信息的方式将 X*
转换为 void*
,以便稍后可以将其转换回 X*
。但是 void*
可能看起来很不一样。
因此编译器可以插入将 X*
更改为 void*
的代码。但是它如何将 char*(*)(X*)
(参数为 X*
的函数)更改为 char*(*)(void*)
?如果函数期望 arg
的类型为 char*(*)(void*)
,那么它很可能会调用 arg(v)
,其中 v
的类型为 void*
。如果 arg
实际上期望 X*
会发生什么?
为了让编译器允许这种可能性,它必须以某种方式将 arg
包装在通常称为蹦床的东西中;一个接受 X*
并将其转换为 void*
以调用不同函数的函数。这不是那么容易——一方面,它必须将蹦床存储在某个地方——所以 C 拒绝将其作为自动转换。
我正在试验类似通用的代码,我有一个这样的函数(删除了很多不相关的代码):
typedef uint8_t (*struct_converter_t)(void *, char *);
void convert_struct(
struct_converter_t converter, // this is a function
const char * file_name
){
some_struct_t * some_struct;
converter(some_struct, some_string_buffer);
}
当我尝试分配一个接受 some_struct_t
(而不是 void *
)的函数时:
static uint8_t some_converter(some_struct_t * vd, char * s);
给我的 struct_converter_t
像这样:
struct_converter_t converter = some_converter; // WARNING HERE
我明白了:
initialization of 'struct_converter_t' {aka 'unsigned char (*)(void *, char *)'} from incompatible pointer type 'uint8_t (*)(some_struct_t *, char *)' {aka 'unsigned char (*)(struct <anonymous> *, char *)'} [-Wincompatible-pointer-types]
我对 C 没有经验,我想知道是否有办法优雅地摆脱这个警告。
您分配给函数指针类型的函数具有与函数指针不兼容的参数。
您的函数将 some_struct_t *
作为第一个参数,但函数指针类型将 void *
作为第一个参数。虽然任何对象指针都可以 to/from 转换为 void *
,但不会扩展到函数指针参数。
您需要更改您的函数,使其第一个参数采用 void *
以与函数指针兼容。然后在函数内部,您可以将 void *
参数转换为 some_struct_t *
.
在 C 中,您可以向需要 void*
的函数提供类型 X*
的参数。但就转换而言,仅此而已。您不能将第一个参数为 X*
的函数用作第一个参数为 void*
.
原因是C不保证X*
和void*
表示相同。它确实保证编译器知道如何以不破坏信息的方式将 X*
转换为 void*
,以便稍后可以将其转换回 X*
。但是 void*
可能看起来很不一样。
因此编译器可以插入将 X*
更改为 void*
的代码。但是它如何将 char*(*)(X*)
(参数为 X*
的函数)更改为 char*(*)(void*)
?如果函数期望 arg
的类型为 char*(*)(void*)
,那么它很可能会调用 arg(v)
,其中 v
的类型为 void*
。如果 arg
实际上期望 X*
会发生什么?
为了让编译器允许这种可能性,它必须以某种方式将 arg
包装在通常称为蹦床的东西中;一个接受 X*
并将其转换为 void*
以调用不同函数的函数。这不是那么容易——一方面,它必须将蹦床存储在某个地方——所以 C 拒绝将其作为自动转换。