12
void f(char* p)
{}

int main()
{
    f("Hello"); // OK

    auto p = "Hello";

    f(p); // error C2664: 'void f(char *)' : cannot convert parameter 1 
          // from 'const char *' to 'char *'
} 

コードはVC++2012年11月CTPでコンパイルされました。

§2.14.15文字列リテラル、セクション7

狭い文字列リテラルの型は「arrayofnconst char」です。ここで、nは以下に定義する文字列のサイズであり、静的な保存期間があります。

なぜf("Hello")大丈夫ですか?

4

4 に答える 4

16

この動作は、少なくとも理論的には、CとC++で異なります。

Cの場合:文字列リテラルは非定数ポインタに減衰します。ただし、それは良い考えではありません。そのポインタを介して文字列を変更しようとすると、未定義の動作が発生します。

C ++の場合:それは決して大丈夫ではありません(AFAIK)。* ただし、一部のコンパイラでは、それでも問題を解決できる場合があります。たとえば、GCCには-Wwrite-stringsフラグがあり、これはデフォルトで有効になっています(少なくとも4.5.1以降)。


* C ++ 11では、少なくとも。(古いスペックはありません。)

于 2013-01-19T14:45:51.503 に答える
7
f("Hello");

これでもC++では問題ありません。コンパイラは診断を行う必要があります。そうでない場合は、更新する必要があります。

C ++では、はではなく、"Hello"に変換できます。const char*char*

"Hello"からへの変換char*はC++03で許可されていますが、非推奨です。また、C ++ 11では、変換が無効であり、コードの形式が正しくありません。

于 2013-01-19T14:46:43.617 に答える
7

の違い

f("Hello");

f(p);

前者はリテラルを含むということです。C ++ 03では、文字列リテラルからchar*(注:ではないconst)への変換がサポートされていました。C ++ 11ではサポートされなくなりましたが、そのルールの変更にまだ追いついているコンパイラはほとんどありません。

于 2013-01-19T14:56:05.383 に答える
-1

自動キーワードだからだと思います。これは型の推論であるため、コンパイラはchar*に変換する方法を認識しなくなります。

于 2013-01-19T14:47:52.257 に答える