web-dev-qa-db-ja.com

文字列リテラルからchar *への変換は非推奨です

コードで「文字列リテラルからchar *への変換は非推奨です」というエラーが表示され続けます。コードの目的は、ポインターツーポインターを使用してstring1およびstring2にWordを割り当て、それを出力することです。どうすれば修正できますか?

これが私のコードです:

#include <iostream>
using namespace std;

struct WORDBLOCK
{
    char* string1;
    char* string2;
};

void f3()
{
    WORDBLOCK Word;

    Word.string1 = "Test1";
    Word.string2 = "Test2";


    char *test1 = Word.string1;
    char *test2 = Word.string2;

    char** teststrings;

    teststrings = &test1;
    *teststrings = test2;

    cout << "The first string is: "
         << teststrings
         << " and your second string is: "
         << *teststrings
         << endl;  
}
26
Andrew T

C++文字列リテラルはconstcharの配列です。つまり、それらを合法的に変更することはできません。

文字列リテラルをポインターに安全に割り当てたい場合(暗黙の配列からポインターへの変換が含まれます)、ターゲットポインターを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(非constchar*を使用すると、ポインターが指すデータを変更できます。文字列リテラル(文字列の最初の文字へのポインターに暗黙的に変換されます)をプレーンなchar*に割り当てることができる場合、コンパイラーからの警告なしにそのポインターを使用して文字列リテラルを変更できます。 。上記の無効なコード機能した場合は印刷されます

Some literal

-一部のシステムでは実際にそうなる場合があります。ただし、私のシステムでは、読み取り専用メモリ(物理ROMではなく、オペレーティングシステムによって読み取り専用としてマークされているメモリ)に書き込もうとするため、セグメンテーション違反で停止します。

(余談:Cの文字列リテラルの規則はC++の規則とは異なります。Cでは、文字列リテラルはcharの配列ですnotconst charの配列-しかし、変更しようとすると未定義の動作になります。つまり、Cではchar *s = "hello"; s[0] = 'H';を合法的に書くことができ、コンパイラは必ずしも文句を言うわけではありませんが、プログラムを実行すると、セグメンテーション違反で停止する可能性があります。これは、constキーワードが導入される前に記述されたCコードとの下位互換性を維持するために行われました。C++には最初からconstがあったため、この特定の妥協は必要ありませんでした。)

44
Keith Thompson