実際、"hello"
タイプはchar const[6]
です。
しかし、質問の要点は依然として正しいです。なぜ C++ では、読み取り専用のメモリ位置を非const
型に割り当てることができるのでしょうか?
これの唯一の理由は、知らなかった古い C コードとの下位互換性const
です。ここで C++ が厳密であった場合、多くの既存のコードが壊れていたでしょう。
とはいえ、ほとんどのコンパイラは、非推奨のコードについて警告するように構成できます。また、デフォルトでそうするように構成することもできます。さらに、C++11 はこれを完全に禁止していますが、コンパイラはまだ強制していない可能性があります。
標準ファン向け:
[参照 1] C++03 標準: §4.2/2
ワイド文字列リテラルではない文字列リテラル (2.13.4) は、「char へのポインタ」型の右辺値に変換できます。ワイド文字列リテラルは、「wchar_t へのポインター」型の右辺値に変換できます。いずれの場合も、結果は配列の最初の要素へのポインターです。この変換は、明示的な適切なポインター ターゲット型がある場合にのみ考慮され、左辺値から右辺値に変換する必要がある場合は考慮されません。[注: この変換は非推奨です. 附属書 D を参照。【例:「abc」は、配列からポインタへの変換で「const charへのポインタ」に変換され、修飾変換で「charへのポインタ」に変換されます。]
C++11 では、C++11 では違法なコードであることを意味する上記の引用を単純に削除しています。
[参照 2] C99 標準 6.4.5/5「文字列リテラル - セマンティクス」:
変換フェーズ 7 では、値ゼロのバイトまたはコードが、文字列リテラルまたはリテラルから生じる各マルチバイト文字シーケンスに追加されます。次に、マルチバイト文字シーケンスを使用して、シーケンスを格納するのに十分な長さの静的ストレージ期間の配列を初期化します。文字列リテラルの場合、配列要素は char 型を持ち、マルチバイト文字シーケンスの個々のバイトで初期化されます。ワイド文字列リテラルの場合、配列要素は wchar_t 型を持ち、ワイド文字のシーケンスで初期化されます...
これらの配列の要素が適切な値を持っている場合、これらの配列が異なるかどうかは指定されていません。プログラムがそのような配列を変更しようとした場合、動作は未定義です。