問題タブ [const-cast]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - const_cast<> に関する動作
const データ メンバーに対する const_cast の動作をチェックするための小さな問題を書きました。
このプログラムを実行した後、"yogendra" (8 文字の文字列) として出力します。そして、「yogendya」として出力されました。今は疑問です。const_cast<> を介して、データ メンバー自体の動作をオーバーライドできます。ここでは文字列が const char* であるため、キャスト後も変更できます。
c++ - const_cast<> 使用時の予期しない出力
以下のコードを machine(devcpp) と codepad.org に書きましたが、マッチングは正常に機能し、codepad.org( http://codepad.org/XfW5a8en ) では出力が文字化けします。
出力が Hello World! になることを期待しています。
c++ - データ変更時のUBの説明
私は仕事仲間に、定数修飾変数の値を本当に変更したい (そしてその方法を知っている) 場合は、いくつかのトリックを使用して変更できることを実証しようとしていましたが、デモ中に 2 つの「フレーバー」が存在することを発見しました定数値:何をしても変更できないものと、汚いトリックを使用して変更できるもの。
コンパイラがスタックに格納された値の代わりにリテラル値を使用する場合、定数値は変更できません(こちらを参照) 。
これにより、次の出力が生成されます。
私はUB(constデータの値を変更する)に依存しているので、プログラムが奇妙な動作をすることが予想されます。しかし、この奇妙さは私が予想していた以上のものです。
コンパイラがリテラル値を使用していると仮定すると、コードが定数の値を変更する命令に到達すると (参照、ポインター、またはmemcpy
ing によって)、値がリテラルである (未定義である) 限り、単に順序を無視します。ただし、動作)。これは、値が変更されない理由を説明していますが、次のとおりです。
- 両方の変数のメモリアドレスが同じなのに、含まれる値が異なるのはなぜですか?
私の知る限り、同じメモリアドレスが異なる値を指すことはできないため、出力の1つが嘘をついています:
- 本当に何が起こっているのですか?偽のメモリアドレスはどれですか (もしあれば)?
上記のコードにいくつかの変更を加えると、リテラル値の使用を避けることができるため、トリックが機能します (ソースはこちら)。
次の出力が生成されます。
ご覧のとおり、const 修飾された変数はchange_with_*
呼び出しごとに変更され、動作はこの事実を除いて以前と同じであるため、const データが使用されたときにメモリ アドレスの奇妙な動作が現れると仮定したくなりました。値ではなくリテラルとして。
したがって、この仮定を確実にするために、unsigned int value
inmain
をに変更して最後のテストを行いましたconst unsigned int value
。
TEST 2
驚いたことに、出力は( code here )と同じであるため、データはパラメーターとして使用されているため、リテラル値ではなく変数として渡されていると思われるため、次のように考えています。
- コンパイラが const 値をリテラル値として最適化することを決定する要因は何ですか?
簡単に言えば、私の質問は次のとおりです。
- で
TEST 1
。- const値とno-const値が同じメモリアドレスを共有しているのに、含まれる値が異なるのはなぜですか?
- この出力を生成するためにプログラムに続く手順は何ですか? 偽のメモリアドレスはどれですか (もしあれば)?
- の
TEST 3
- コンパイラが const 値をリテラル値として最適化することを決定する要因は何ですか?
c++ - C++ で参照を返すオーバーロードされた const および非 const クラス メソッド
一部のオブジェクト (大きい場合があります) へのアクセサーを持つ C++ のデータ構造クラスがあり、このアクセサーを使用する const メソッドと非 const メソッドがあるため、オーバーロードする必要があります。以下のコードの批評を探しています - 同じことをよりクリーンに達成する方法はありますか?
私が理解しているように、次のケースでアクセサーのコードを複製せずにこれを実現するには、get() メソッドの 2 つの方法があります。これら 2 つの方法のいずれかに重大な問題があるかどうかはわかりません。ここでいくつかのガイダンスをお願いします。
私が方法 A を気に入っている理由は次のとおりです。
- 1 つの const_cast のみ
- メソッド get() の const-version はコピーを返します
- 非 const メソッドは、非 const 参照を直接取得します
私は方法Aが好きではありません:
- 非 const メソッド get() は契約によってのみ const になります (コンパイラによってチェックされません)。
- const 参照を取得するのは難しいが、不可能ではない
私が方法 B を気に入っている理由は次のとおりです。
- const メソッド get() の const-ness は、コンパイラによってチェックされます
- 返されたオブジェクトのコピーはユーザーによって制御されます
私は方法Bが好きではありません:
- 読みにくい 2 つの const_casts が必要です
これは、2 つのケースの (最小限の) コード例です。
c++ - C++ const_cast は変数の const-ness を削除しません
以下のプログラムを実行してみました。
出力は次のとおりです。
私が知っていることから、 const_cast は変更可能であるため、変更できます。*ptr を表示すると変更が反映されますが、aでは変更が反映されません。誰でも説明できますか?
編集:すべての回答をありがとう。未定義の動作を観察していることがわかります。そして、最初はmutableと *const_cast* を混同していました。それでは、どのようなシナリオで const_cast を使用するのか教えていただけますか?
c++ - BOOST_FOREACH および cxxtest プラグインでのキャスティングの問題
私は現在、私が使用するプロジェクトに取り組んでいます:
- ブースト ライブラリ v1.39
- Eclipse CDT (Juno) と Cygwin
- CxxTest プラグイン: http://wiki.web-cat.org/WCWiki/EclipsePlugins/CxxTestPlugin
に関する問題に遭遇しましたconst_cast
。私は高低を検索しましたが、私を助けることができる情報源をオンラインで見つけられませんでした. BOOST_FOREACH
テストメソッド内で呼び出すと、問題が発生します。次のエラーが発生し続けます。
const_cast_helper
私は問題の分析を開始し、 const_cast 演算子がランタイム チェックの目的でオーバーロードされていることを発見しました。全体Dereferee::const_cast_helper
として、cxxtest 依存関係の一部である、const_cast 演算子のオーバーロードがあります。
このヘルパーは const_cast 演算子を定義解除します (!)
最後に const_cast 演算子を再導入します。
#define const_cast ::Dereferee::const_cast_helper
const_cast が呼び出されるたびに、このヘルパーの適切なコンストラクターが呼び出されるようにします。コンストラクターは、ポインター、参照、const ポインター、および const 参照を受け入れます。
rvalue_probe
Boost はまた、反復されるコレクションが左辺値または右辺値であるかどうかを確認するためにキャストをいじり、それをコピーしたり式を再計算したりするのを回避します。
コンパイラは、次のように文句を言います。
私の場合、T は boost::unordered_map であり、どういうわけかこのキャストとヘルパーのオーバーロードの組み合わせが壊れています...
それを解決する方法は?
考えられる解決策を調べましたが、実際にそれらを実装する方法がわかりません。C++ の経験があまりありません。テストでこれらのコンパイル時のチェックを行うかどうかは少し気にしません。それを回避できます。したがって、3 つの方向のいずれかのヘルプが最も役立ちます。
ブーストの右辺値チェックを無効にし、BOOST_WORKAROUND と foreach.hpp で定義されたリテラルで遊んでいます。
BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION BOOST_FOREACH_NO_RVALUE_DETECTION BOOST_FOREACH_NO_CONST_RVALUE_DETECTION BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION
これを無効にし
const_cast_helper
ます。テスト プログラム (テスト プロジェクトとは別のプロジェクト) を実行すると、コードがコンパイルされて期待どおりに実行され、const_cast のオーバーロードによって問題が発生しました。このエラーを修正する拡張機能を実装します。でやるべきかどうかはわかりませんが、
const_cast_helper
何rvalue_probe
の役にも立ちませんでした。
template <typename T> const_cast_helper(rvalue_probe<U>* value_to_cast) : cast_value(const_cast<U*>(value_to_cast)) { }
事前にご入力いただきありがとうございます。