希望这是一个简单的C ++问题(不是语言律师问题)。
如何在C ++中使用GNU扩展dladdr
?通常会在C中写下以下内容:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
static void where_am_i() {}
int main()
{
Dl_info info;
dladdr( (void*)&where_am_i, &info );
return 0;
}
然而,使用clang可以看到演员表可能无效:
$ clang --version
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ clang -Wpedantic -o foo foo.cpp -ldl
foo.cpp:11:11: warning: cast between pointer-to-function and pointer-to-object is an extension [-Wpedantic]
dladdr( (void*)&where_am_i, &info );
^~~~~~~~~~~~~~~~~~
1 warning generated.
警告对我来说似乎合法,所以有办法解决这个问题吗?
答案 0 :(得分:2)
没有标准方法可以将函数指针可移植地转换为void*
。因此,没有可移植地使用dladdr
的标准方法。在C ++ 11之前,这种转换是不正确的(我没有提供该文档,但clang的警告暗示了这一点)。但是,从C ++ 11开始,有条件地支持转换:
[expr.reinterpret.cast] / 8(标准草案)
有条件地支持将函数指针转换为对象指针类型,反之亦然。这种转换的含义是实现定义的,除非实现支持两个方向的转换,将一种类型的prvalue转换为另一种类型并返回,可能具有不同的cv-qualification,将产生原始指针值。 / p>
由于您已经依赖于提供dladdr
的c库扩展,因此您可能依赖于允许您将函数指针强制转换为void*
的语言扩展。在这种情况下,您可能希望编译器不通过编译而不使用-Wpedantic
选项来警告使用语言扩展 - 或者使用至少有条件地支持转换的标准版本。如果不支持转换,则不会dladdr
。