C ++文字列リテラルはconst char
の配列です。つまり、合法的に変更することはできません。
文字列リテラルをポインタに安全に割り当てたい場合(暗黙的な配列からポインタへの変換を含む)、ターゲットポインタをとしてconst char*
だけでなく、として宣言する必要がありますchar*
。
警告なしにコンパイルされるコードのバージョンは次のとおりです。
#include <iostream>
using namespace std;
struct WORDBLOCK
{
const char* string1;
const char* string2;
};
void f3()
{
WORDBLOCK word;
word.string1 = "Test1";
word.string2 = "Test2";
const char *test1 = word.string1;
const char *test2 = word.string2;
const char** teststrings;
teststrings = &test1;
*teststrings = test2;
cout << "The first string is: "
<< teststrings
<< " and your second string is: "
<< *teststrings
<< endl;
}
言語がこの制限を課さなかった場合に何が起こる可能性があるかを考えてみてください。
#include <iostream>
int main() {
char *ptr = "some literal"; // This is invalid
*ptr = 'S';
std::cout << ptr << "\n";
}
A(非const
)char*
を使用すると、ポインタが指すデータを変更できます。文字列リテラル(文字列の最初の文字へのポインタに暗黙的に変換される)をプレーンに割り当てることができればchar*
、コンパイラからの警告なしに、そのポインタを使用して文字列リテラルを変更できます。上記の無効なコードが機能した場合、
Some literal
-そしてそれは実際にいくつかのシステムでそうするかもしれません。ただし、私のシステムでは、読み取り専用メモリ(物理ROMではなく、オペレーティングシステムによって読み取り専用としてマークされているメモリ)に書き込もうとするため、セグメンテーション違反で停止します。
(余談ですが、文字列リテラルに関するCの規則はC ++の規則とは異なります。Cでは、文字列リテラルは-の配列でchar
はなく、の配列ですconst char
が、変更しようとすると未定義の動作になります。これは、Cで合法的に記述できることを意味します。char *s = "hello"; s[0] = 'H';
、コンパイラは必ずしも文句を言うわけではありませんが、実行するとプログラムがセグメンテーションエラーで終了する可能性があります。これは、const
キーワードが導入される前に記述されたCコードとの下位互換性を維持するために行われました。C++はconst
最初からありました。 、したがって、この特定の妥協は必要ありませんでした。)