2017-08-05 9 views
0

は、G ++ 4.8.2(32ビットSTD = C++ 98)との大規模なレガシーアプリケーションを再コンパイルは、新しい警告は、Gに警告なしにコンパイルwarning: cast to pointer from integer of different size [-Wint-to-pointer-cast]Cの文字列へのC++参照は可能ですか?

コードを言っデータシリアライザの部分から飛び出し++ 4.4 。7。

この警告は、「char &」をシリアライズするテンプレート関数から得られます。コメントには、NULLで終了する文字列への参照が含まれています。

私はC++を初めて使っています...はありませんconst char& 1文字への参照ですか? Cのヌル終了文字列の開始アドレスとしてこの参照を使用しないのは、ある種の不正行為ですか?

警告を無視するか、そうでない場合は、この構成に適切なフォーム(存在する場合)は何ですか?

//! Implementations of write() for null-terminated strings. 
void write(DvCsr::TName, const char* v, long = NO_INDEX) {writeCStr(v);} 
void write(DvCsr::TName, const u_char* v, long = NO_INDEX) {writeCStr(v);} 
void write(DvCsr::TName, const char& v, long = NO_INDEX) {writeRefCStr(v);} 
void write(DvCsr::TName, const u_char& v, long = NO_INDEX) {writeRefCStr(v);} 

//! Write null-terminated string data types to the stream. 
template <class T> 
void writeCStr(const T* start) 
{ 
    // Find length of the string, not including null terminator, 
    // and size (in bytes), including null terminator. 
    const T* end = start; 
    while (*end++) 
     ; 
    size_t len = end - start; 

    // Add the string to the end of the buffer. 
    mBuffer.reserve(mBuffer.size() + len); 
    std::copy(start, start + len, std::back_inserter(mBuffer)); 
}; 

template <class T> 
void writeRefCStr(const T &start) 
{ 
    writeCStr((unsigned char *)start); 
} 
+1

良いルール:警告を無視して常に '-pedantic -Wall'でコンパイルしないでください – Rakete1111

+1

@ Rakete1111' -Wextra'を(少なくとも)それに追加します。 –

+0

@JesperJuhlこの場合、 '-pedantic-errors -Werror'も追加します:P – Rakete1111

答えて

0

これは問題です:

// Definition 
void write(DvCsr::TName, const char& v, long = NO_INDEX) {writeRefCStr(v);} 

// Call 
void writeRefCStr(const T &start){ 
    writeCStr((unsigned char *)start); 
} 

あなたが書くことstartを使用しています。あなたが書くことstartアドレスを使用しているように、代わりにあなたは...

writeCStr((unsigned char *) &start); 
           ^

をする必要があります。

参照は、既存のオブジェクトの本質的に変更不可能なエイリアスです。参照として渡されたときにそのアドレスを取得しません。あなたは自分自身になっています。参照のためにアドレス演算子&を使用する必要があります。

+0

これで魔法のようにヌル終了することはありません。 – Rakete1111

+0

@ Rakete1111 OPが関数を正しく呼び出しているとしましょう。 – iBug

+0

これは誤った仮定です。なぜなら、関数がどのように呼び出されているのか(コメントを除く最初の4行は)、文字列で呼び出されていないからです。 – Rakete1111

0

文字列を扱う場合は、2文字のバッファを割り当てて、NULLで終了するようにする必要があります。

void writeRefCStr(const T & start){ const char tmp [2] = {start、0}; writeCStr(tmp); // tmpはconst char *と同じです。 }

1

2つの基本的な問題があります。まず、1文字をポインタにキャストしています。そのアドレスは&startです。次に、const&から非constポインタにキャストしています。このポインタは未定義の動作を与えます。 reintrpret_castが好まれるようC++はキャストそれよう

template <class T> 
void writeRefCStr(const T& start) 
{ 
    // use &start to obtain its address 
    // 
    // use reinterpret_cast so the compiler complains about the 
    // lack of const (and make it a const unsigned char*) 
    // 
    writeCStr(reinterpret_cast<const unsigned char*>(&start)); 
} 

(unsigned char*)別名、いわゆる「Cスタイルキャストは、」すべてのコンパイラの警告を削除します。

関連する問題