2017-04-20 3 views
1

は、簡単なプログラム、次の点を考慮:それはVC++に罰金コンパイルが、g++ & clang++は、コンパイルエラーを与えるC++、g ++/clang ++ vs vC++の関数のアドレスを表示しますか?

#include <iostream> 
void foo() { } 
int main() { 
    std::cout<<static_cast<void*>(foo); 
} 

source_file.cpp: In function ‘int main()’: 
source_file.cpp:4:38: error: invalid static_cast from type ‘void()’ to type ‘void*’ 
    std::cout<<static_cast<void*>(foo); 
           ^

はライブデモhereVC++

を参照してくださいライブデモhereclang++

を参照してくださいライブデモg++ & clang++で与えhereg++

診断を参照してください。

C++標準によれば、ここでどのコンパイラが正しいのでしょうか?私は、ここではg++ & clang++の動作が正しいと思います。 static_castの代わりにreinterpret_castをここで使用する必要があることを知っています。 VC++コンパイラでこのバグはありますか?答えがC++の特定の標準に依存している場合は、それについても知りたいと思っています。 this pointers-to-void referenceから

+0

fooは関数ポインタに減衰します。 – Destructor

+0

MSVCの正しさを望むなら、最近追加された '/ permissive-'でMSVC14.1を使用してください。また、VC++の代わりにMSVCと呼ばれることもあります。 – tambre

答えて

9

実行しようとしている変換がstatic_castで実行可能な変換の中にないため、GCCとClangは正しいです。これらの変換は[expr.static.cast]に列挙されます。基準変換(P2)参照互換型(P3)直接のためのオペランドを使用して

  • 変換はxValueへ
  • 変換由来する

    • ベース:私は簡単にそのセクションの段落を参照して、それらをまとめます-initialization(P4)標準変換シーケンス(P7)
    • 整数/列挙変換(P9、P10)のvoidへ
    • 変換(P6)
    • ポインタ変換(P13)

    オブジェクトを0

  • 塩基由来するポインタ変換(P11)
  • ベースポインタツー部材変換(P12)に由来
  • ボイドポインタは更に、P5は言う:

    他の変換は、static_castを使用して明示的に実行してはなりません。

    関数または関数ポインタのvoid*への変換は、リストされている変換に含まれていません。

    特に、関数ポインタからvoid*への標準変換がないため、直接初期化は適用されません。/2 [conv.ptr]によれば:

    タイプのprvalue Tがオブジェクト型である「ポインタCVTに」、CVへのポインタ 」タイプのprvalueに変換することができます。void "。オブジェクトタイプへのポインタの非ヌルポインタ値を「 cvvoidへのポインタ」に変換した結果は、元のポインタ値と同じバイトのアドレスを表す。 nullポインタ の値は、宛先タイプのNULLポインタ値に変換されます。

    これは、関数ポインタではなくオブジェクトポインタのみを対象としています。

  • 1

    :任意のタイプのオブジェクト

    ポインタが暗黙的void

    へのポインタに変換することができる[重点鉱山]

    そしてfrom this function reference

    関数へのポインタは、単にvoid*に変換できないことを示しているように見える関数オブジェクトではありません

    +0

    これはどのコンパイラが正しいかという質問には答えません。だから、あなたが標準的な引用を思いついた方が良いでしょう! – Destructor

    +0

    @Destructor更新された回答 –

    関連する問題