【C言語】文字列リテラルのデータ型について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ユーマ
記事: 33
登録日時: 6年前

【C言語】文字列リテラルのデータ型について

#1

投稿記事 by ユーマ » 4年前

こんにちは。
最近、Windows10の上でVisualStudio2019を使用してC言語のプログラミングをしていると気になったことができたので質問させていただきました。

気になったことというのは「文字列リテラル」についてです。
普段、自分はUbuntuの上でgccを用いてプログラミングしているのですが、いつもは文字列リテラルのアドレスを持つポインタを初期化する際、次のようなコードを書いていました。(gcc -dumpversionで調べると、gccのバージョンは7でした)

コード:

int main(void){
    char* str = "hello, world";
    return 0;
}
このコードはgccでは問題なくコンパイルされました。
しかし、これをVisualStudioでためしてみると次のようなエラーが出ます。

コード:

 '初期化中': 'const char [13]' から 'char *' に変換できません。
僕は文字列リテラルは読み込み専用領域に配置されると学んだので(環境によっては違うのかもしれませんが...)VisualStudioの対応が正しいと思うのですが、gccによると問題ないみたいです。
gccの側で文字列リテラルの中身を書き換えようとした場合はしっかりsegmentation faultがでます。
つまり、文字列リテラルはconst charの配列ということですよね?
これはgccの手抜き(??)という認識で正しいのでしょうか?
どなたか知識をお貸しください。

Bull
記事: 149
登録日時: 9年前

Re: 【C言語】文字列リテラルのデータ型について

#2

投稿記事 by Bull » 4年前

まず、これは C言語ではなく C++ ではないですか?
C言語でこのエラーはでないはずです。

歴史的経緯もあって以前の規格 (C++98/C++03) では、char * を文字列リテラルで初期化するのは許容されていました。C++11 以降の規格では禁止されました。Visual Studio (VC) でもオプションなしではエラーになりません。
Visual Studio でプロジェクトを作成するとデフォルトで /permissive- オプションが設定され、エラーになります。
/permissive- オプションなしにすると過去のバージョンとの互換性を重視して、規格に厳密に準拠しなくなります。

gcc でもオプションによってはエラーあるいは警告が出ます。-Werror=write-strings オプションを指定するとエラーになり、-Wwrite-strings オプションでは警告が出ます。

vc や gcc でデフォルトでエラーにしない理由はよく判りませんが、過去に作られたソースを修正なしにコンパイルするためかもしれません。

いずれにしても文字列リテラルは書き換え禁止なので const char * が正しいです。過去のソースはともかく新規に作成されるソースは const char * にすべきですね。

返信

“C言語何でも質問掲示板” へ戻る