2011-12-25 8 views
1

double (*)(double)double(*)(...)にキャストしても安全かどうかは分かりませんが、これは複数の関数へのポインタを持つコードを一般化するために使用されます。C++:関数へのポインタをキャストするのは安全ですか?

これまでは、関数に渡されるすべてのものをベクトルに格納していましたが、(正しい数の引数を渡して)関数を呼び出す方法があるかどうかは疑問です一般化されたコード?私は何か、この意味:

//while initializing 
mFunction = sin; 
//later in code 
double (*generalized)(...) = mFunction; 
for(i=0;i<args.size();i++) 
    pusharg(args[i]); 
call(generalized); 

--edit--

saftlyアセンブリを使用して関数を呼び出すためにそれが可能であるC++を使用してそれを行うための有効な方法が存在しない場合は?

+0

まあ、そうではありません!私は "関数ポインタ"から "他の署名付き関数へのポインタ"にキャストしようとしていますが、 "void *"を "関数ポインタ"にキャストしようとしています – Ali1S232

答えて

3

double(*)(double)double(*)(...)に直接割り当てることはできませんが、reinterpret_castとすることができます。キャストは、明示的に§5.2.10[expr.reinterpret.cast]/6によって許可されていますが、キャスト関数ポインタを呼び出すと、未定義の動作が発生します:

関数ポインタ明示的に関数ポインタに変換することができます別のタイプの

関数の定義で使用されている型と同じではない関数型へのポインタによる関数の呼び出しの影響は、は未定義です。

元のタイプに戻す(T1T2は関数型である)「T2へのポインタ」型に「T1へのポインタ」型のprvalue変換とはポインタ値の結果が得られることを除きそのようなポインタ変換は不特定である。

なぜそれがUBにつながるのか分かります。generalized(1.0, 2.0, 3.0)と呼ぶとどうなりますか?これにより、コールスタックが破損する可能性があります。しかし、電話する前にgeneralizeddouble(*)(double)にキャストしても問題ありません。

+0

私的メンバーなので、プログラマの間違いを心配する必要があります。 'sin(double)'を 'generalize(double、...)'に変換した場合、 'generalize(1.0)'と呼ぶか、 'hypot(double、double)'ならば、 'generalize(1.0,2。0) ' – Ali1S232

+0

@Gajet:エラーを避けるためにできるだけ元の型にキャストする方が良いです。 '...'は呼び出し規約を変更する可能性があります(例えば 'float'を' ... '引数に渡すと、関数を呼び出す前に' double'に変換されます)。 – kennytm

1

はい、キャスト自体は許可されています。しかし、間違った署名でそれを呼び出すことはできません。ジェネリック関数ポインタを使用する場合は、void (*)()を使用するほうが良いでしょう。ただし、関数ポインタの場合はvoid*のようになります(暗黙的に変換する必要はありません)。

さらに具体的な引数を付けるので、std::functionstd::bind(コンパイラがC++ 11ライブラリをサポートしている場合)、またはそれらのBoostに相当するものを使用してください。

+0

" 'void(*)(boost :: noncopyable)'のように、呼び出すことができないポインタを使用したいと思います。 – curiousguy

+0

私のためのトリックを行う同等のアセンブリコードはありますか? – Ali1S232

+0

@Gajet:あなたが知っているように、組み立ては非常に難しいです。しかしそれは可能です。呼び出しコードは、基本的にいくつかのアセンブリ行になるので、私は自分のデリゲートクラスを使ってそれを楽しんで実装しました。しかし、それは非常にバグがあり、問題を引き起こす可能性が高いことに注意してください。 – Xeo

0

generalizedをvolatileにすると、コンパイラはABI仕様に従う必要があります。宣言されていないC関数をサポートしたいという要望のために、固定数の引数で関数へのポインタを使用しても、可変数の引数を除く関数を呼び出さなければ、ほとんどのABI(x86とx86-32を含む)では安全です。 。

関連する問題