12

是否有任何 g++ 选项可以检测到 std::string 与 NULL const char* 的不正确初始化?

我正在将一些 int 字段转换为 std::string 字段,即:

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

...转换成:

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

我完全忽略了使用 0 和 g++ 进行的糟糕的“id”初始化,根本没有给我任何警告。在运行时检测到此错误(std::string 构造函数引发异常),但我真的很想在编译时检测到这些东西。有什么办法吗?

4

3 回答 3

8

我想不出在编译时检测到这一点的方法,所以我编写了一个正确处理空指针的字符串生成器函数:

//  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 中)-Wnonnull在 C++ 中不受支持,并且该属性显然被忽略了。为什么会这样并不明显。也许感觉它与超载或其他东西相互作用很糟糕。

于 2010-03-09T13:23:55.020 回答