2012-12-02 111 views
2

GCC allows customization of printf specifiers.但是,我沒有看到如何「教」它接受我的字符串類%s說明符。我的字符串類是一個簡單的字符指針包裝器,並且只有一個成員變量(char * data)並且沒有虛函數。因此,將它按原樣傳遞給printf-like函數代替常規的char *是可以的。問題是gcc靜態分析器阻止我這樣做,我必須明確地將它轉換爲const char *以避免警告或錯誤。GCC:爲字符串輸出定製printf

我的CString看起來是這樣的:

class cstring 
{ 
    cstring() : data(NULL){} 
    cstring(const char * str) : data(strdup(str)){} 
    cstring(const cstring & str) : data(strdup(str.data)){} 
    ~cstring() 
    { 
     free(data); 
    } 
    ... 
    const char * c_str() const 
    { 
     return data; 
    } 

private: 
    char * data; 
}; 

示例代碼,使用的CString:

cstring str("my string"); 
printf("str: '%s'", str); 

在GCC我得到這個錯誤:
錯誤:無法傳遞的對象非trivially- ''''類'cstring'到'
錯誤:格式'%s'需要類型'char *'的參數,但參數1具有類型'cstring'[-Werror = format]
cc1plus.exe:將所有警告視爲錯誤

回答

1

C++標準不要求編譯器支持此類代碼,並且並非所有版本的gcc都支持它。 (https://gcc.gnu.org/onlinedocs/gcc/Conditionally-supported-behavior.html表明gcc-6.0至少 - 這個問題是否會與類似的類一起工作)。

C++ 11標準中的相關部分是5.2.2第7部分:

When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg ... Passing a potentially-evaluated argument of class type (Clause 9) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.

(但看看光明的一面:如果你進入使用c_str的習慣,那麼至少你不會得到絆倒,當/如果你使用std::string。)