Avoiding improper std::string initialization with NULL const char* using g++

旧街凉风 提交于 2019-12-01 00:17:06

问题


A there any g++ options which can detect improper initialization of std::string with NULL const char*?

I was in the process of turning some int fields into std::string ones, i.e:

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

...turned into:

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

I completely overlooked bad 'id' initialization with 0 and g++ gave me no warnings at all. This error was detected in the run time(std::string constructor threw an exception) but I'd really like to detect such stuff in the compile time. Is there any way?


回答1:


I think it is actually undefined behavior and not checked by the compiler. You are lucky that this implementation throws an exception.

However, you can avoid such problems by specifying that you want default or zero-initialization in a type-agnostic way:

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};



回答2:


I can't think of a way to detect this at compile-time, so I wrote a string builder function that properly deals with null pointers:

//  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);
}

I use this whenever I create a string and there's a chance the input might be NULL.




回答3:


There is infrastructure in GCC to produce exactly this sort of warning:

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

void bar() {
    foo(0);
}

when compiled with -Wnonnull (which is implied by -Wall) produces:

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

So in principle you ought to be able to modify the relevant system header (or, better for experimenting, modify your own $HOME/bits/basic_string.h copy and then override the system one with -isystem $HOME) similarly:

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

However this doesn't help because (at least in 4.0.1) -Wnonnull is not supported in C++ and the attribute is apparently ignored. It's not obvious why this is so; perhaps it was felt that it interacted badly with overloading or something.



来源:https://stackoverflow.com/questions/2407711/avoiding-improper-stdstring-initialization-with-null-const-char-using-g

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!