2017-10-05 10 views
3

次のコードは、GCCの上にきれいにコンパイルしますが、クラン上のエラーを取得します。constを関数ポインタにキャストする方法はありますか?

typedef void (MyFuncPtr)(); 
void foo(const MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

クランエラー:

error: cannot initialize a variable of type 'MyFuncPtr *' (aka 'void (*)()') with an lvalue of type 'const MyFuncPtr *' 
    (aka 'void (const *)()') 

私は次の解決方法を試してみましたし、彼らはすべてのC-スタイル以外のエラーが出ますキャスト:

はconst_cast:

MyFuncPtr* myTestPtr = const_cast<MyFuncPtr*>(ptr); 

エラー:

error: const_cast to 'MyFuncPtr *' (aka 'void (*)()'), which is not a reference, pointer-to-object, or pointer-to-data-member 

reintepret_cast:

MyFuncPtr* myTestPtr = reinterpret_cast<MyFuncPtr*>(ptr); 

エラー:

error: reinterpret_cast from 'const MyFuncPtr *' (aka 'void (const *)()') to 'MyFuncPtr *' (aka 'void (*)()') casts away 
    qualifiers 

Cスタイルのキャスト:

MyFuncPtr* myTestPtr = (MyFuncPtr*) ptr; 

成功!

質問:
const_castが関数ポインタで機能しないのはなぜですか?
Cスタイルのキャストのみを使用していますか?
これはGCCでキャストなしで動作するのはなぜですか?

ありがとうございます!

コンパイラのバージョン:あなたのコードで
* G ++バージョン4.6.3
*打ち鳴らすバージョン3.5.0.210790

+0

'const MyFuncPtr *'型はほとんどナンセンスで無駄です(ほぼ完全に役に立たない)。そして、私が考えることができるすべての使用には*インスタンス*が関連付けられていません。なぜあなたはあなたのプログラムにこのタイプを持っていますか?非常に汎用的なコードですか? – Yakk

+3

'MyFuncPtr'は実際には関数型ではなく、関数ポインタ型ではないことに注意してください(これはあなたの質問を無効にしませんが、実際はもっと面白くなります) –

答えて

3

MyFuncPtrは関数型(ない関数ポインタ型)です。あなたのコードは、タイプconst MyFuncPtrを使用しようとします。これは、関数タイプにconstを適用しています。

しかし、C++ 14 [dcl.fct]/6でメモによれば、const修飾関数型のようなものは存在しない。

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. —end note ]

このセクションでは、主に約を話しているがcv-qualifier-seqは、メンバ関数の後に続く修飾子です。しかし、一般的に、関数型に適用されるcv修飾子は無視されることを指定しているようです。打ち鳴らすがエラーを報告するために盗聴さを意味します

typedef void (MyFuncPtr)(); 
void foo(MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

だからあなたのコードは同じであるべきです。

+0

私はこの例ではC++ 11を使用しています回答? – Chadness3

+0

clangバージョン3.7では、3::3:10:警告:関数型 'MyFuncPtr'(別名void() ')の警告:' const '修飾子は効果がありません[ -vignored-qualifiers] void foo(const MyFuncPtr * ptr) – Chadness3

+0

@ Chadness3 OK、clangはすでに3.5のバグを見つけて3.7 –

関連する問題