4
char* foo = "fpp"; //compile in vs 2010 with no problem

文字列リテラルはconstchar*型ですが。
また、constタイプをnon-constタイプに割り当てることはできません。
だから私は上記のコードが失敗することを期待していますか、それとも何かが欠けていますか?

編集:申し訳ありませんが、コンパイラも警告をスローすることを完全に忘れました。
私はずっとエラーリストを見ていました。
それを確認するのを忘れています。

Edit2:プロジェクトの警告レベルをEnableAllWarnings(/ Wall)に設定しましたが、これに関する警告はありません。
だから私の質問はまだ有効です。

4

7 に答える 7

6

C++03 では、 [参照 1]constキーワードなしで文字列リテラルを使用することは非推奨です。

[参照 1] C++03 標準: §4.2/2

ワイド文字列リテラルではない文字列リテラル (2.13.4) は、「char へのポインタ」型の右辺値に変換できます。ワイド文字列リテラルは、「wchar_t へのポインター」型の右辺値に変換できます。いずれの場合も、結果は配列の最初の要素へのポインターです。この変換は、明示的な適切なポインター ターゲット型がある場合にのみ考慮され、左辺値から右辺値に変換する必要がある場合は考慮されません。[注: この変換は非推奨です. 附属書 D を参照。【例:「abc」は、配列からポインタへの変換で「const charへのポインタ」に変換され、修飾変換で「charへのポインタ」に変換されます。]

C++11 は、C++11 では違法なコードであることを意味する上記の引用を単純に削除します。

C++03 より前の C++ では、constキーワードを使用せずに文字列リテラルの宣言を派生させていました。同じことが C でも完全に有効であることに注意してください。

于 2012-11-06T09:52:17.773 に答える
4

私が理解しているように、Cでは以前constに追加されましたが、これは文字列をポインターに割り当てる方法でした。

C++ では、これは非推奨の動作ですが、下位互換性を維持するために引き続き許可されています。使用しないでください。

実際、C++11 では完全に無効だと思います。

于 2012-11-06T09:51:22.203 に答える
2

そうではありません。文字列リテラルはchar*型に割り当て可能です。文字列リテラルは変更しないでください。

constこの奇妙な状況は、存在する以前のプログラムとの後方互換性のためです。

于 2012-11-06T09:50:29.160 に答える
1

gcc -std=c++0xこれについて警告します:

a.cpp:5:14:警告:文字列定数から'char*'への非推奨の変換[-Wwrite-strings]

したがって、これは引き続き許可されますが、リテラル文字列がconstであるため、非推奨になります。

于 2012-11-06T09:54:01.750 に答える
1

あなたは実際にはcharのベクトルであるC文字列について話している。C++ では、クラスstd::stringが使用され、定数文字列が として作成されconst std::stringます。

とにかく、コンパイラは、ソースコードに表示されるリテラル文字列を格納するために、将来のプログラムでメモリの一部を予約します。メモリのこの部分は読み取り専用と見なされるため、const char *. サイズは、文字列のサイズに、末尾のゼロの位置を 1 つ加えた正確なサイズであり、文字列の終わりを示します。

コンパイラは下位互換性を維持する必要があるため、 が指すリテラルを引き続き受け入れますchar *。ただし、組み込みシステムの ROM に格納できるメモリを変更できるとは想定されていないため、これは誤解を招く可能性があります。

私のシステムでは、clang を使用しています。

$ clang --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: i386-pc-linux-gnu
Thread model: posix

clang C コンパイラでは、このコードはエラーなしでコンパイルされます。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char * str = "Hello, World!";

    printf( "%s", str );

    return EXIT_SUCCESS;
}

ただし、まったく同じコード (ヘッダーの名前などの小さな変更を加えたもの) を C++ プログラムとしてコンパイルすると、次の警告がスローされます。

kk.cpp:6:15: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
        char * str = "Hello, World!";
                     ^
1 warning generated.

お役に立てれば。

于 2012-11-06T10:02:18.447 に答える
1

const 型などというものはありません。Const キーワードは、いわゆる型修飾子です。これは任意のポインター型に適用でき、ポインターが指す値を変更してはならないことを意味します。

次のように const 修飾子をポインター参照自体に適用することもできます。

char* const p ="aaa";

これにより、ポインター変数が別の文字列を指さないように保護されます。

于 2012-11-06T09:54:56.717 に答える
1

これをサポートするための特別な暗黙の変換があります。これは、レガシー コード (const存在する前に書かれることが多い) の一般的なイディオムであるためです。文字列リテラルの型はchar const[]であり、そのまま使用する必要があります。変換が導入された瞬間から廃止されたため、優れたコンパイラは上記で警告します。

これは、文字列リテラルの型が C とは異なることに注意してくださいchar[](ただし、それを変更しようとすると、未定義の動作になります)。

于 2012-11-06T09:54:57.933 に答える