我最近询问了有关 GLib 中某些代码的完全相同的问题。(GLib 是 GNOME 项目的核心库,用 C 语言编写。)有人告诉我,整个 slot'n'signals 框架都依赖于它。
在整个代码中,有许多从类型 (1) 到 (2) 的强制转换实例:
typedef int (*CompareFunc) (const void *a,
const void *b)
typedef int (*CompareDataFunc) (const void *b,
const void *b,
void *user_data)
像这样的调用链通是很常见的:
int stuff_equal (GStuff *a,
GStuff *b,
CompareFunc compare_func)
{
return stuff_equal_with_data(a, b, (CompareDataFunc) compare_func, NULL);
}
int stuff_equal_with_data (GStuff *a,
GStuff *b,
CompareDataFunc compare_func,
void *user_data)
{
int result;
/* do some work here */
result = compare_func (data1, data2, user_data);
return result;
}
在此处亲自查看g_array_sort()
:http ://git.gnome.org/browse/glib/tree/glib/garray.c
上面的答案很详细,而且很可能是正确的——如果你是标准委员会的成员的话。Adam 和 Johannes 值得称赞他们经过充分研究的回应。但是,在野外,您会发现此代码运行良好。有争议的?是的。考虑一下:GLib 在大量平台(Linux/Solaris/Windows/OS X)上使用各种编译器/链接器/内核加载器(GCC/CLang/MSVC)编译/工作/测试。标准该死,我猜。
我花了一些时间思考这些答案。这是我的结论:
- 如果您正在编写回调库,这可能没问题。警告购买者 - 使用风险自负。
- 否则,不要这样做。
在写下这个回复之后深入思考,如果 C 编译器的代码使用相同的技巧,我不会感到惊讶。而且由于(大多数/全部?)现代 C 编译器是自举的,这意味着这个技巧是安全的。
一个更重要的研究问题:有人能找到这个技巧不起作用的平台/编译器/链接器/加载器吗?那个主要的布朗尼点。我敢打赌,有些嵌入式处理器/系统不喜欢它。然而,对于桌面计算(可能还有移动/平板电脑),这个技巧可能仍然有效。