2010-03-09 42 views
10

有沒有任何g ++選項可以檢測不正確的初始化std :: string與NULL const char *?避免不正確的std ::字符串初始化與空const char *使用g ++

我是在轉彎一些int字段成的std :: string的人的過程,即:

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

...變成了:

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

我完全忽略壞的 '身份證'用0和g ++初始化完全沒有給我警告。這個錯誤是在運行時檢測到的(std :: string構造函數拋出一個異常),但我真的很想在編譯時檢測這些東西。有什麼辦法嗎?

+2

不幸的是,0是一個不會觸發從int到指針的無效轉換錯誤的值。因爲0是一個空指針常量,所以可以轉換爲任何指針類型。除了像訪問者說的那樣,我不知道你能做的任何事情,而不是首先寫出初始化器。 – 2010-03-09 11:23:32

+0

正確的解決辦法是添加一個私有構造函數'std :: string :: string(int);'。這會更好地匹配,從而導致編譯時錯誤。 – MSalters 2010-03-09 11:47:12

+1

不確定你是否以這種方式表示,但實際上它可以起到一次性測試的作用,可以捕獲從「int」到「string」這一輪更改所導致的任何錯誤。修改g ++標準頭文件中的'std :: basic_string',檢查新代碼是否編譯,然後在任何人發佈之前快速更改它。 – 2010-03-09 12:01:15

回答

5

我認爲它實際上是未定義的行爲,並沒有被編譯器檢查。你很幸運,這個實現引發了一個異常。

但是,您可以通過指定要默認或類型無關的方式零初始化避免這樣的問題:

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

嗯...所以你說默認構造函數爲int類型分配0? – pachanga 2010-03-11 17:46:05

+3

此語法表示內置類型的零初始化。 – visitor 2010-03-12 09:40:00

+0

感謝您的信息! – pachanga 2010-03-28 07:07:19

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 /位/ basic_string.h複製,然後覆蓋系統中的一個與-isystem $HOME)相似:

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

但是這並沒有幫助,因爲C++不支持(至少在4.0.1)-Wnonnull,並且該屬性顯然被忽略。這並不是顯而易見的原因。也許有人認爲它與超載或某事有很大的相互作用。

+1

其實你上面的'basic_string' ctor'__attribute __((nonnull(1)))'檢查'this'指針不是'NULL';只需改變爲'__attribute __((nonnull(2)))'來檢查'__s'是否爲非空;請參閱http://gcc.gnu.org/ml/gcc/2006-04/msg00549.html – vladr 2012-03-11 03:50:51

7

我不能想辦法在編譯時檢測到這一點,所以我寫了一個字符串生成器功能,與空指針正常交易:

// 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。