5

$5.2.11/7 - 「[注: オブジェクトの型に応じて、const-qualifier68 をキャストする const_cast から生じるデータ メンバーへのポインター、左辺値、またはポインターを介した書き込み操作は、未定義の動作を引き起こす可能性があります (7.1. 5.1).]"

このセクション (C++03) の文言は、私にとって驚くべきものです。驚くべきことは2つあります。

a) まず、'may' の使い方。なぜ「かもしれない」なのですか?標準の他の場所は、未定義の動作について非常に明確です

b) もともと const オブジェクトの constness をキャストしても、すぐに「未定義の動作」にならないのはなぜですか。UB をトリガーするために書き込みが必要なのはなぜですか?

4

4 に答える 4

6

a) まず、'may' の使い方。なぜ「かもしれない」なのですか?標準の他の場所は、未定義の動作について非常に明確です

ここでは、 mayという言葉の使用法をあまり深く調べないでください。ポイントは、この場合 constness をキャストすると、未定義の動作が発生することです。

C++ 標準では、次のように「may」または「might」を頻繁に使用します。

1.3.12:この国際規格が動作の明示的な定義の記述を省略している場合、未定義の動作も予想される場合があります

鉱山を強調します。基本的に、規格では「許可されている」のように「かもしれません」という言葉を使用しています。

b) もともと const オブジェクトの constness をキャストしても、すぐに「未定義の動作」にならないのはなぜですか。UB をトリガーするために書き込みが必要なのはなぜですか?

特定のプラットフォームでは const オブジェクトが読み取り専用メモリに格納される可能性があるため、書き込みによって UB がトリガーされます。

于 2010-10-28T12:02:30.320 に答える
5

私の理解では、問題のオブジェクトが基本的に const ポインターではなく const オブジェクトである場合、または元々 const ではなかったオブジェクトへの参照である場合にのみ、UB になるということです。

基本的に const であるデータをメモリの読み取り専用部分にロードでき、そこへの書き込みは機能しないという考えです。ただし、問題のオブジェクトが基本的に可変である場合は、適切に機能することが保証されています。

元:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.

以下のコメントについては、コメントでコードがひどいように見えるためです。

標準の §7.1. 5.1/4 では、次の例が示されています。

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object

したがって、これは特に許可されています。

于 2010-10-28T12:01:27.400 に答える
3

最初の質問については、何か未定義の動作を生成する可能性がある場合、それはそれを未定義にすることはありません。

2 番目の部分については、相互運用性の理由によるものだと思います。たとえば、C にはキーワードがない (または C99 以前はなかった)constため、const オブジェクトを C 関数に渡したい場合は、constness をキャストする必要があります。そのため、C++ 標準では、書き込みが実行されない限りこれが許可されると規定されています。C 関数が読み取り専用の場合、constness は安全にキャストできます。

C++ でも、一貫性のない、または不完全な const-correctness はかなり一般的です。そのため、引数を変更しない関数に const オブジェクトを渡すために、const 性をキャストしなければならない状況にときどき遭遇しますが、非 const で受け取ります。

于 2010-10-28T12:13:07.070 に答える
1

constこれは、オブジェクトを読み取り専用メモリに格納できるためだと思います。したがって、書き込みは、プログラムのクラッシュ、セグメンテーション違反、または影響なしなど、さまざまな影響を与える可能性があります。

于 2010-10-28T12:01:08.213 に答える