5

VS2010 はエラー C2440 を示しています:'return' : cannot convert from 'char *' to 'const char *&以下f3char*戻り値の型が のときにa を返すことができないのはなぜconst char*&ですか?

const char* const& f1()
{
    static char* x = new char[5]();
    return x;
}

char* const& f2()
{
    static char* x = new char[5]();
    return x;
}

const char* & f3()
{
    static char* x = new char[5]();
    return x;    // error C2440
}

char* & f4()
{
    static char* x = new char[5]();
    return x;
}
4

3 に答える 3

5
于 2013-03-27T22:40:17.003 に答える
2
#include <iostream>
void problem( const char*& output, const char* input )
{
  output = input; // legal, const char*& = const char*
}

int main() {
  const char buff[] = "hello";
  char* out = nullptr;
  problem( const_cast<const char*&>(out), &buff[0] );
  out[0] = 'H'; // I just changed a const array's first character
  std::cout << &buff[0] << "\n";
}

これは、未定義の動作を行った証拠である "Hello" を出力します。そのためには、 を使用する必要がありましたconst_castconst char*&をで初期化できれば、未定義の動作を呼び出すためにchar*を実行する必要はありません。const_cast

「しかし」「これはOPが投稿した正確なケースと一致しません!」と言う人もいるかもしれません。

これは本当です。

// the "legal" way to do what the OP wants to do, but it leads to undefined
// behavior:
const char*& problem2( char*& c ) { return const_cast<const char*&>(c); }
void problem3( const char*& left, const char* right ) { left = right; }

#include <iostream>
int main() {
  char* c = nullptr;
  char const* buff = "hello undefined behavior";
  problem3( problem2(c), buff );
  c[0] = 'H';
  std::cout << buff << "\n";
}

「Hello undefined behavior」も出力します。

「しかし」、「あなたは を に変えたのであって、 を に変えchar*&たのconst char*&ではない。char*const char*&

結構:

void problem3( const char*& left, const char* right ) { left = right; }
const char*& problem4( char x = 0 ) {
  static char* bob = nullptr;
  if (bob && x)
    bob[0] = x;
  return const_cast<const char*&>(bob);
}
#include <iostream>
int main() {
  char const* buff = "hello problem";
  problem3( problem4(), buff );
  problem4('H');
  std::cout << buff << "\n";
}

繰り返しになりますが、その罪を犯す資本H(まあ、実際には、通常は資本である未定義の動作H) です。

于 2013-03-27T22:41:03.533 に答える
2

char **同じ理由で、 from からto にキャストすることはできませんconst char **。そうでなければ、あなたは書くことができます

f3() = "hello";

f3 への後続の呼び出しは、静的 local にエイリアス化された文字列リテラルのメモリに書き込むことができますx

于 2013-03-27T21:51:43.290 に答える