我想使用自定义的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 |发布于 2015-03-20 16:02:15
目前还没有这样的办法。见这个gcc虫。
修改GCC以公开一些用于printf检查的内部机制并不太难,这样就可以编写一个能够理解您添加内容的GCC插件。不过,这确实需要对GCC有点熟悉。
发布于 2018-05-22 12:51:42
虽然没有直接的方法来注册针对-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]);
}概念的证明可以找到这里。
https://stackoverflow.com/questions/29160437
复制相似问题