c-指针的运行时类型检查



我想知道scanf函数是如何实现的。(当然只是为了好玩)参数的数量是可变的,所以它肯定是由va_listva_arg宏实现的。

当参数的数量和格式字符串不匹配时,它还会抛出一些警告。这可以通过解析格式字符串并将其与参数数量进行比较来完成。没有魔法。

我唯一看不到如何实现的是类型检查。当参数的类型(指向数据的指针)和格式文字中相应的声明不匹配时,scanf会产生警告。如何检查指针指向的数据类型?

示例:

#include<stdio.h>
int main()
{
char buffer1[32], buffer2[32];
int n; 
double x;
scanf("%s %s %d",buffer1, buffer2, &x); // warning
scanf("%s %s %d",buffer1, buffer2, &n); // ok
}

输出:

warning: format ‘%d’ expects argument of type ‘int *’,
but argument 4 has type ‘double *’ [-Wformat]

AFAIK C库不是C语言/编译器的一部分,因此<stdio.h>中没有任何与语言相关的内容。我假设警告是由scanf的实现产生的,而不是由编译器[?]产生的。(可能使用#warning)

如果我想在某些代码中做类似的事情,我如何知道指针指向的是哪种数据类型?

注意:我已经下载了GNU C库的源代码,并查看了scanf.c。我在这个非常复杂的代码中找不到路。有很多#ifndef和对其他具有奇怪名称和结构的函数的调用。。。

此检查由gcc编译器处理,特别是针对scanf/printf函数。

这是一个常见的错误,因此值得为这些函数的编译器添加特殊情况代码。

请参阅此处的GCC-WFormat标志:http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options.html

-Wformat:检查对printf和scanf等的调用,以确保提供的参数具有适合格式字符串的类型指定,并且格式字符串中指定的转换说得通。这包括标准功能,以及格式化属性(请参见函数属性),在printf、scanf、,strftime和strfmon(X/Open扩展,不在C标准中)家庭。

这些检查并不是所有编译器都能实现的,所以它肯定不是可以依赖的。

使用GCC,您可以使用函数属性"format"one_answers"format arg"来告诉编译器对您的函数应用相同的检查。

format(原型,字符串索引,第一个检查)format属性指定函数采用printf、scanf、strftime或strfmon样式参数,应该根据格式字符串进行类型检查。例如,声明:

extern int my_printf (void *my_object, const char *my_format, ...)  
__attribute__ ((format (printf, 2, 3)));

。。。使编译器检查my_printf调用中的参数是否与printf样式的格式字符串参数一致my_format。

警告由编译器生成。您将x声明为double,因此它知道&xdouble*。然后,它扫描格式字符串,发现该格式需要int*,因此发出警告。

相关内容

  • 没有找到相关文章

最新更新