【问题标题】:GCC: Customizing printf for string outputGCC:为字符串输出定制 printf
【发布时间】:2012-12-02 23:49:27
【问题描述】:

GCC allows customization of printf specifiers. 但是,我不知道如何“教”它接受 %s 说明符的字符串类。我的字符串类是对 char 指针的简单包装,并且只有一个成员变量(char * 数据)并且没有虚函数。因此,可以按原样将其传递给类似 printf 的函数来代替常规的 char *。问题是 gcc 静态分析器阻止我这样做,我必须将其显式转换为 const char * 以避免警告或错误。

我的 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 上出现此错误:
错误:无法通过“...”传递非平凡可复制类型“class cstring”的对象
错误:格式“%s”需要“char*”类型的参数,但参数 1 的类型为“cstring”[-Werror=format]
cc1plus.exe:所有警告都被视为错误

【问题讨论】:

    标签: gcc printf


    【解决方案1】:

    C++ 标准不要求编译器支持此类代码,而且并非所有版本的 gcc 都支持它。 (https://gcc.gnu.org/onlinedocs/gcc/Conditionally-supported-behavior.html 建议 gcc-6.0 至少可以 - 一个悬而未决的问题,它是否可以与这里的类一起工作。)

    C++11标准中的相关章节是5.2.2 section 7:

    当给定参数没有参数时,参数的传递方式使得接收函数可以通过调用 va_arg ... 传递类类型的潜在评估参数(第 9 条) 有一个不平凡的复制构造函数,一个不平凡的移动构造函数, 或一个不重要的析构函数,没有相应的参数,是 有条件地支持实现定义的语义。

    (但看好的一面:如果你养成使用c_str的习惯,那么至少你不会在使用std::string时被绊倒。)

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多