27

RTTI を無効にし-fno-rttiて (GCC または/GR-Visual Studio で) 動的キャストを使用してコードをコンパイルするとどうなるか知りたいです。コンパイラは に「フォールバック」しstatic_castますか? (少なくともVSでは)警告を発行するだけなので、コンパイルされたコードは何をしますか?

より具体的には、RTTI を使用せずに、dynamic_cast でエラーが発生しないと確信しているコード (つまり、dynamic_cast安全に a に置き換えることができる場所static_cast) を次のようにコンパイルすると、どのような問題が発生する可能性がありますか?

class A{ /*...*/ } ;
class B : public A {
    int foo() { return 42 ;}
} ;
//...
A * myA = new B() ;
int bar = (dynamic_cast<B*>(myA))->foo() ;
4

4 に答える 4

13

標準を読むと、5.2.7/6 で、ターゲットがソースの明確なベースでない限り、ソースは多態型でなければならないことがわかります。その後、10.3/1 で

仮想関数は、動的バインディングとオブジェクト指向プログラミングをサポートします。仮想関数を宣言または継承するクラスは、ポリモーフィック クラスと呼ばれます。

言い換えれば、標準はあなたの質問について何も言っていないようです。この場合、標準ではコンパイラが RTTI をオフにすることを許可していないため、コンパイラごとにドキュメントをチェックして何が起こるかを確認する必要があります。この読み取りに基づいて、これはタグが示すように C++ 言語の質問ではなく、コンパイラの質問だと思います。

static_castまたは、十分であることがわかっているときに使用するだけで、問題を完全に回避できます。

于 2011-10-07T13:46:39.063 に答える
10

MSVC では、コードが RTTI を有効にしてコンパイルされていない__non_rtti_object場合、ランタイム チェックなしでキャストを実行できない場合、例外がスローされます。

于 2011-10-07T14:38:08.287 に答える
6

最も簡単な方法は、試してみることです。

動的キャストの一部が違法としてフラグ付けされることがわかります。しない人もいます。たとえば、動的キャストを使用して明確な基本クラスにアップキャストする場合、変換はコンパイル時に認識されます。

補遺
Re「(少なくともVSでは)警告を発行するだけなので...」危険を冒して警告を無視してください。最善の方法は、コードが警告なしでコンパイルされ、警告レベルが非常に高く設定されている (場合によってはエラーに変換される) ことを確認することです。2 番目に良いのは、受け取ったすべての警告を調べて、不都合なことが起こらないようにすることです。この場合、不都合なことが起こります。その厄介なイベントがどのように実装されているかは本当に気にする必要はありません。あなたが気にするべきことは、それを取り除くことです。

于 2011-10-07T12:21:43.663 に答える