【发布时间】:2023-04-05 00:17:01
【问题描述】:
我有一个代码生成脚本,它是由其他人在 2008 年左右编写的,从那时起几乎没有变化,运行良好。就在最近我尝试使用 gcc9 进行编译时,我在生成的代码中看到了 7300 条“不兼容函数类型之间的强制转换”警告。
代码采用一组函数指针和各种类型标识符,并将所有内容插入到一个大映射中,稍后用于选项序列化、打印等。许多函数和变量被转换并存储为某种形式的 void *。否则代码编译没有错误并且可以正常工作。
我尝试了各种 C 风格的强制转换、reinterpret_cast 以及将函数指针强制转换为 void(*)(void),但它们都没有消除警告。将函数转换为泛型类型以避免此警告的正确方法是什么?我能想出的唯一解决方案是禁用 -Wcast-function-type。
这是一个生成警告的示例行:
pim.must_find("input_fn")->set_introspect_info( sizeof(filename_t), ((char *)(&p_cn->input_fn)) - ((char *)p_cn), 0,invalid_offset, (str_from_base_t *)str_from_filename_t, (send_base_t *)send_filename_t, (recv_base_t *)recv_filename_t, (val_from_param_t *)val_from_param_filename_t, 0);
警告与这两个功能有关:
typedef std::string str_from_base_t( void const * );
std::string str_from_filename_t( filename_t const & v ) { return v; }
其中 filename_t 是一个从 std::string 插入的类。
请注意,有许多不同的 str_from_***() 函数具有不同的类作为参数。
我得到的警告是:
../src/gen/DEFReader_PostParam.cc: In function 'void croix::DEFReaderCLI_introspect_pim_init()':
../src/gen/DEFReader_PostParam.cc:25:153: warning: cast between incompatible function types from 'std::string (*)(const croix::filename_t&)' {aka 'std::basic_string<char> (*)(const croix::filename_t&)'} to 'std::string (*)(const void*)' {aka 'std::basic_string<char> (*)(const void*)'} [-Wcast-function-type]
25 | pim.must_find("input_fn")->set_introspect_info( sizeof(filename_t), ((char *)(&p_cn->input_fn)) - ((char *)p_cn), 0,invalid_offset, (str_from_base_t *)str_from_filename_t, (send_base_t *)send_filename_t, (recv_base_t *)recv_filename_t, (val_from_param_t *)val_from_param_filename_t, 0);
【问题讨论】:
-
将函数转换为泛型类型以避免此警告的正确方法是什么? -- 你为什么认为有一种“正确”的方法?也许你所做的事情是不正确的,到目前为止你还没有被它咬过。应用 C 风格的转换来避免编译器警告和错误是在某些时候可能会出错的迹象。
-
好的,那么将采用各种不同单类参数的函数指针插入同一个映射的正确方法是什么?我需要找到一种更简洁的方法来完成这项工作,而无需重写所有内容,因为我并不完全了解整个系统应该如何工作。这是大型商业软件代码库的选项处理部分。
-
本应设计的方式是使用函数对象,并具有函数对象成员的参数部分。然后从基础对象派生,每个子类覆盖
operator ()。我知道这不是一个答案,而是作为如何防止将来陷入这种情况的指南。 -
Here is a tiny example。一张地图,多个“功能”,都有不同的签名,绝对没有进行任何转换,也没有
void*。诀窍是参数已从函数调用转移到成员变量,operator()的魔力开始发挥作用。 -
我需要找到一种更简洁的方法来完成这项工作,而无需重写所有内容,因为我并不完全了解整个系统应该如何工作。 -- I不要认为你需要了解完整的系统。你知道那张地图和演员应该做什么(理论上)。所以这是一个重新实现它的问题,知道最终结果应该是什么。如果您不知道地图的用途、函数指针是什么等,那就另当别论了。
标签: c++ function-pointers