2016-09-15 14 views
6

これはむしろ単純なC++の質問です(言語弁護士ではない)。dladdr:ポインタへのポインタ対オブジェクトへのポインタ

C++でGNU拡張dladdrをどのように使用するのですか?通常、1は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; 
} 

1は、キャストが無効である可能性が見ることができる打ち鳴らすを使用して:

$ 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. 

警告はそう回避する方法があり、私には合法的なようですそれ ?

+1

いいえ、それは "dl" APIの一般的な制限です。 C言語で動作することが保証されていない方法で、関数ポインタをvoidポインタにパッケージ化しますが、Posixは関数ポインタを保持できるようにvoidポインタを必要とします( "dl"関数はPosixの一部です)。 –

+0

このように書く方が良い: 'void * p;/* dl ... */* reinterpret_cast (&where_am_i)= p; ' –

+0

私たちはここでC++コードについて話しています。 –

答えて

2

ファンクションポインタをvoid*に移植する標準的な方法はありません。そのため、移植可能な標準的な方法はありませんdladdr。 C++ 11以前は、このような変換が正しく行われていませんでした(私はこの文書を入手できませんでしたが、clangによる警告がそれを示唆しています)。 C++ 11しかし、変換が条件付きでサポートされている:

[expr.reinterpret.cast]/8(規格案)

オブジェクトポインタ型、またはその逆への関数ポインタを変換条件付き支持されています。このような変換の意味は、インプリメンテーションが両方向の変換をサポートしている場合、あるタイプの正当値を他のタイプに変換し、おそらく異なるcv修飾を使用して元のポインタ値を返すことを除いて、


すでにdladdrを提供するCライブラリの拡張機能に依存しているので、あなたにも、あなたがvoid*に関数ポインタをキャストすることができます言語拡張に依存しているかもしれません。その場合、-Wpedanticオプションなしでコンパイルして言語拡張を使用することについて警告しないようにコンパイラに依頼したり、変換が少なくとも条件付きでサポートされている標準バージョンを使用したりすることができます。変換がサポートされていない場合は、dladdrではありません。

関連する問題