12

NULL const char* を使用した std::string の不適切な初期化を検出できる g++ オプションはありますか?

私はいくつかの int フィールドを std::string フィールドに変換する過程にありました。

struct Foo
{
   int id;
   Foo() : id(0) {} 
};

...になって:

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};

0 による不正な 'id' 初期化を完全に見落としており、g++ は警告をまったく表示しませんでした。このエラーは実行時に検出されました (std::string コンストラクターが例外をスローしました) が、コンパイル時にそのようなものを検出したいと思っています。何か方法はありますか?

4

3 に答える 3

8

コンパイル時にこれを検出する方法を考えることができないので、nullポインターを適切に処理する文字列ビルダー関数を作成しました。

//  FUNCTION :      safe_string(char const* pszS)
//  PARAMATERS :    pszS        source string to build a string from (may be NULL or 0-length)
//  DESCRIPTION :   Safely builds a string object from a char*, even a NULL pointer
//  RETURNS :       string

template<class C>
inline basic_string<C> safe_string(const C* input)
{
    if( !input )
        return basic_string<C>();
    return basic_string<C>(input);
}

文字列を作成するときはいつでもこれを使用し、入力がNULLになる可能性があります。

于 2010-03-09T14:59:37.783 に答える
5

実際には未定義の動作であり、コンパイラによってチェックされていないと思います。この実装が例外をスローすることは幸運です。

ただし、タイプにとらわれない方法でデフォルトまたはゼロ初期化を指定することで、このような問題を回避できます。

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};
于 2010-03-09T10:03:34.260 に答える
2

GCC には、まさにこの種の警告を生成するインフラストラクチャがあります。

void foo(const char* cstr) __attribute__((nonnull (1)));

void bar() {
    foo(0);
}

でコンパイルすると-Wnonnull( によって暗示されます-Wall)、以下が生成されます。

warning: null argument where non-null required (argument 1)

したがって、原則として、関連するシステム ヘッダーを変更できる必要があります (または、実験には、独自の $HOME/bits/basic_string.h コピーを変更してから、システム ヘッダーを でオーバーライドします-isystem $HOME)。

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
    __attribute__((nonnull (1)));

ただし、(少なくとも 4.0.1 では) -WnonnullC++ でサポートされておらず、属性が明らかに無視されているため、これは役に立ちません。なぜそうなのかは明らかではありません。おそらく、オーバーロードなどとの相性が悪いと感じたのでしょう。

于 2010-03-09T13:23:55.020 に答える