2017-10-31 6 views
2

なぜ、C++コンパイラは次のコードに対して文句を言わないのですか?なぜchar *へのcharの追加についてコンパイラが不平を言っていませんか?

#include<iostream> 
int main() 
{ 
    const char* p ="Hello"; 
    std::string q = p + 'H'; 
    std::cout << q << std::endl; 
} 

そして、それは間違いなく次のコードコンパイラによってスロー

#include<iostream> 
int main() 
{ 
    const char* p ="Hello"; 
    std::string q = p + "World"; 
    std::cout << q << std::endl; 
} 

エラー文のエラーを投げ

最初のコードがスローされなかった理由

は、誰かが理解し、私を助けることができる

test.cxx: In function 'int main()': 
test.cxx:5: error: invalid operands of types 'const char*' and 'const char [6]' to binary 'operator+' 
エラー文?

+0

** 'H' **のためにある可能性があります。 'std :: string q = p + 'H';'、** "H"で試してください** –

答えて

6

'H'は、文字、整数型です。したがってp + 'H'&p['H']と同じです(数値は'H'に基づいてインデックスを作成しています)。最初のスニペットでは、数値が'H'であるため、未定義の動作をしている可能性がありますが、コンパイラは未定義の動作については不平を言っていません。

一方、"World"は整数型でも、1に変換可能でもありません。したがって、追加は実行できません。ブランクを指します。

2

'H'は、シングル文字であり、そのタイプはcharです。 charは暗黙的にintに変換されるので、この値をポインタp(その値で進める)に追加します。

新しいポインタqが配列の外側を指しているため、未定義の動作です。

2

両方とも、(予想通り)文字列の連結を実行しません。

p + 'H'の場合、ポインタ演算が実行されます。 'H'が値72の整数として扱われた場合、p + 'H'は配列"Hello"の73番目の要素を指すポインタを返そうとしますが、それは境界から外れており、UBにつながります。コンパイラーはそのための診断を発行する必要はありません。

p + "World"の場合、2つのポインタ(つまり、const char*)を追加していますが、意味がありません。

私は、例えば、あなたが代わりにstd::string p ="Hello";のようなポインタのstd::stringを使用し、または(C++ 14から)string literalsを使用する必要があり、あなたは文字列concatenatationをしたいと仮定std::string q = p + "World"s;は、両方ともあなたのために文字列の連結を実行します。

0

charリテラル 'H'を追加すると、他の有効なchar値がcharに追加されるのに対し、「Hello」を追加すると明らかに互換性のない型の文字列へのポインタが追加されることになります。このステートメントで

2

std::string q = p + "World"; 

"World"文字列リテラルは、その最初の文字へのポインタに変換し、タイプconst char *を持っています。

したがって、2つのポインタを追加しようとしています。このような操作は定義されておらず、コンパイラはエラーを出しました。この文で

std::string q = p + 'H'; 

(すなわち、暗黙によるポインタと一体促進にタイプintに変換された整数値'H'を追加する有効な操作が使用されている。すなわち、使用される式でありますコンパイラは、結果ポインタが文字列リテラルを超えているかどうかをチェックしないため、診断は発行されません。

関連する問題