我正在编写一个编译器,我想在printf
中实现类型检查:
printf("%f", i);
warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
printf("%f", 1);
~~ ^~
%d
如您所见,gcc知道%f的含义,并尝试警告我类型不匹配。
那么我该如何实现呢?
P.S。有没有机会没有奥秘,只有gcc为printf写一个特殊规则?
答案 0 :(得分:2)
这是documentation of -Wformat
中所述的两个特殊规则的组合。
printf
函数是built in,它使GCC可以优化它并警告其滥用。关于printf
的特定情况,在documentation中有一条注释:
此外,当某个功能被识别为内置功能时,GCC可能会使用有关该功能的信息来警告对该功能调用的问题,或者生成更有效的代码,即使结果代码仍包含调用该功能。例如,内置
-Wformat
且已知printf
不会修改全局内存时,printf
会给对strlen
的错误调用发出警告。
此外,出于警告目的,您可以使用format
attribute将自己的函数声明为类似于printf的函数。
__attribute__((__format__(__printf__, 2, 3))) /*printf-like function, the format string is parameter 2, the first element is parameter 3*/
int myprintf(int stuff, const char *format, ...);
通过内置函数,GCC尝试用更有效的方法代替函数调用。对于printf
,这通常意味着,当format参数是字符串文字时,GCC将其替换为一系列调用以打印各个元素。例如,很可能像程序包含printf("%d %s\n", x, s);
一样编译__some_internal_function_to_print_a_dcimal_integer__(x); putc(' '); puts(s);
。当编译器执行此优化时,它将注意到格式字符串和参数类型之间的任何不匹配,并进行相应的警告。如果该函数不是内置函数,但具有format
属性,则只会收到警告。