gcc: mixing -Wformat and register_printf_specifier
gcc: mixing -Wformat and register_printf_specifier
我想使用自定义的printf格式标志(通过gcc的register_printf_specifier
),同时仍然可以获得-Wformat
和-Werror
编译器标志的好处。
在下面的例子中,我已经使用自定义的%W
标志打印了我的小部件,但我必须禁用-Wformat
和-Wformat-extra-args
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"
有可能两全其美吗?
我想我的问题可以归结为:有没有办法用-Wformat
注册格式说明符和相关类型?
示例:
#include <cstdio>
#include <cstdlib>
#include <printf.h>
struct Widget
{
const char* name;
};
int print_widget(FILE* stream, const struct printf_info* info, const void* const* args)
{
const Widget* widget = *((const Widget**)(args[0]));
return fprintf(stream, "%*s", (info->left ? -info->width : info->width), widget->name);
}
int print_widget_arginfo(const struct printf_info*, size_t n, int* argtypes, int* size)
{
if (n > 0)
{
argtypes[0] = PA_POINTER;
size[0] = sizeof (Widget *);
}
return 1;
}
int main(void)
{
register_printf_specifier('W', print_widget, print_widget_arginfo);
Widget widget { "foobar" };
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"
printf("|%W|n", &widget);
printf("|%35W|n", &widget);
printf("|%-35W|n", &widget);
}
输出:
|foobar|
| foobar|
|foobar |
目前没有这样的方法。请参阅此gcc错误。
修改GCC以暴露其用于printf
检查的一些内部机制并不难,从而可以编写一个理解您添加内容的GCC插件。不过,它确实需要对GCC有一点熟悉。
尽管没有直接的方法针对-Wformat
注册新的说明符,但有一种解决方法。您可以重载%p
本身,并检测它是否应该是Widget*
。一种方法是将一个特殊值编码到宽度中,并让说明符代码检测该特殊值。例如,
#define IS_WIDGET(INFO) (((INFO)->width & MASK) == WIDGET)
int print_widget(FILE* stream, const struct printf_info* info,
const void* const* args)
{
if (IS_WIDGET(info)) return print_widget_impl(stream, info, args);
return fprintf(stream, "%#*llx",
(info->left ? -info->width : info->width),
(unsigned long long)*(void **)args[0]);
}
概念证明可以在这里找到。
相关文章:
- 为什么在C的循环中使用printf的Rust代码不显示输出,而在C++的循环中显示std::cout
- 内联程序集printf将整数解释为地址
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- C++ Setter/Getter,cout 工作,printf 失败
- Printf 命令不打印时添加了查找常见除数的新代码
- SIGSEGV, 分段错误. 而 printf() 数组索引的值
- 为什么在包含iostream时可以使用printf()?
- "Missing type specifier - int assumed"无法通过向主函数添加"return 0"来解决
- 创建具有验证和语法突出显示的自定义 printf
- 0x%08lx 格式说明符在 printf 语句到 cout
- 由于"error C4430: missing type specifier - int assumed. Note: C++ does not support default-int",我现在无法编
- C printf 无法从终端按预期工作
- Printf 和 Echo 提供不同的输出
- C++ - scanf() 和 printf() 执行顺序不对
- cout 打印不准确的结果,printf 打印准确的结果
- 了解 printf 格式规范中的 %03.3u
- redefine printf(), sprintf(), etc. arm-none-eabi toolchain
- 为什么 printf 在 C++ 中的执行速度比 cout 快?另外scanf比cin慢,为什么?
- C++, printf vs cout performance
- printf 数据类型说明符复杂问题