3

以下を参照してください。

struct A
{
    std::string* get() const
    {
        //return const_cast<std::string*>(&m_pObj);
        return &const_cast<A*>(this)->m_pObj;
    }

    std::string m_pObj;
};

UBconst_castの間接参照ですか?ポインターの定数をthis逆参照してもUBが呼び出されない場合はありますか?const_cast

(上記の例は悪い習慣であり、悪い設計であり、可変で解決できることを私は知っています-それは重要ではありません)

4

4 に答える 4

9

このUBのconst_castを間接参照していますか?const_castingの結果を逆参照しても、ポインターのconstnessがUBを呼び出さない場合はありますか?

常にではありませんが、オブジェクトconst(Aインスタンスはconst A x;であり、逆参照を使用してデータを変更する場合に限ります。読み取りにのみ使用される場合、未定義動作にはなりません。オブジェクトがconstでない場合(まったくない場合もあれば、const-non-constオブジェクトへの参照である場合もあります)、UBにもなりません。

于 2012-06-15T15:45:48.370 に答える
3

いいえ、参照されたオブジェクトが最初に宣言され、その後キャストによって取得されたデータを変更した場合にのみUBにconstなります(§5.2.11/7および§7.1.6.1/4)。以下は合法です:

A a;
a.get()->clear();

これはそうではありませんが(したがってUBです):

A const a;
a.get()->clear();
于 2012-06-15T15:44:43.067 に答える
1

いいえ。ウィットに:

5.2.2関数呼び出し

5 [注:関数は非定数パラメーターの値を変更できますが、パラメーターが参照型(8.3.2)である場合を除いて、これらの変更は引数の値に影響を与えることはできません。参照がconst修飾型への参照である場合、引数の値を変更するためにconst_castを使用してconstnessをキャストする必要があります。パラメータがconst参照型の場合、必要に応じて一時オブジェクトが導入されます(7.1.6、2.14、2.14.5、8.3.4、12.2)。さらに、ポインタパラメータを使用して非定数オブジェクトの値を変更することができます。—エンドノート]

でも、

5.2.11コンストキャスト

12 [注:cv-qualificationの変更のみを含む一部の変換は、const_castを使用して実行できません。たとえば、関数へのポインタ間の変換は、その使用が未定義の動作を引き起こす値につながるため、カバーされていません。同じ理由で、メンバー関数へのポインター間の変換、特に、c​​onstメンバー関数へのポインターから非constメンバー関数へのポインターへの変換はカバーされていません。—エンドノート]

于 2012-06-15T15:46:29.883 に答える
0

コンパイラはconst値を読み取り専用メモリに自由に格納でき、プログラムを最適化するときに値が変更されないことを自由に想定できます。不変性を捨てると、コンパイラとの契約が破られることになり、技術的にはが起こる可能性もあります。

現実的には、コンパイラがconst_cast-ingによって壊れるようなことをすることは非常にまれですが、理論的には可能です。

于 2012-06-15T15:57:23.567 に答える