2

いくつかのレガシーコードをアップグレードすると、g ++から「警告:'Identifier :: Identifier(int)'[-Wconversion-null]の非ポインター引数1にNULLを渡す」というメッセージが表示されるようになりました。ほとんどの場合、これは良いことですが、複数のコンストラクターを持つクラスを考慮に入れていないようです。

たとえば、次のテストコードを考えてみましょう。

#include <stdio.h>

class Identifier
{
  private:
    int m_iID;

  public:
    Identifier(const char* p_c) { m_iID = p_c ? p_c[0] : 0; }
    Identifier(int i) { m_iID = i; }
};

int main(int argc, char* argv[])
{
  Identifier* p_ID = new Identifier(NULL);

  return 0;
}

(コンストラクターが実際に行うことは無視してください。これは問題の単なる説明です。コンテキストとして、問題のコードは、ハッシュ値の形式で識別子を格納するクラスです。コンストラクターは、文字列を使用して変換することができます。ハッシュ、または直接ハッシュ値。)

最後から3行目の「new」ステートメントはこの警告をスローします。私を困惑させているのは、g ++は明らかにIdentifier(int i)コンストラクターを使用する必要があると想定しておりポインターであるIdentifier(const char * p_c)コンストラクターを無視していることです。

intをunsignedintに変更すると、代わりにあいまいさエラーが発生することに注意してください。これは32ビットシステムです。

-Wno-conversion-nullを指定すると、0を渡すか、明示的にNULLをconst char *にキャストするのと同様に、問題が修正されることを私は知っています。しかし、なぜ一見有効なコンストラクターが無視されているのか興味があります。さらに、警告をアクティブにしたまま、大規模な検索と置換のジョブを回避したいと思います。

4

1 に答える 1

2

少なくともこのCentOSボックスでは、NULLは次のように定義されていlinux/stddef.hます。

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

そのため、C++のNULL整数です。したがって、コンパイラーはintデフォルトでコンストラクターを選択し、表示されている警告を表示します。

于 2013-01-16T12:56:15.143 に答える