[英]how to call a function whose name is the same of the local variable name in c
[英]Why does C language allow users to create Macros whose name are the same as a pre-existing library function?
# include <stdio.h>
# define scanf "%s Hello World"
int main (void)
{
printf(scanf, scanf);
getchar();
return 0;
}
在上面的代码片段中,在代码执行之前,发生了宏扩展阶段。 在此,每次出现的 'scanf' 都被替换为"%s Hello World"
。
因此printf(scanf,scanf)
将变为printf(“%s Hello World”, “%s Hello World”)
。
最终的 output 将是:
%s Hello World Hello World
现在,这个程序没有遇到任何问题,因为我们在这里没有使用scanf function。
但是,如果我们出于某种目的使用 scanf function
# include <stdio.h>
# define scanf "%s Hello World"
int main(void)
{
int x;
printf(scanf, scanf);
scanf("%d",&x);
getchar();
return 0;
}
我们遇到一个错误:
main.c: In function ‘main’:
main.c:2:17: error: called object is not a function or function pointer
# define scanf "%s Hello World"
^
main.c:7:4: note: in expansion of macro ‘scanf’
scanf("%d",&x);
^~~~~
那么为什么 C 首先允许我们以 Scanf 之类的库函数命名宏?
C 2018 7.1.3 1 说:
…在以下任何子条款(包括未来的库方向)中列出的文件 scope 的每个标识符(包括未来的库方向)都保留用作宏名称,并且如果包含任何关联的标头,则作为文件 scope 的标识符在同一名称空间中使用。
scanf
是带有文件 scope 的标识符,列在以下子条款 (7.21) 中,并且包含其 header, ,因此保留用作宏名称。
7.1.3 2 说:
... 如果程序在保留标识符的上下文中声明或定义标识符(7.1.4 允许的除外),或将保留标识符定义为宏名称,则行为未定义。
结合起来,这些规则表明,如果您将scanf
定义为宏名称并包含<stdio.h>
,则 C 标准不会对发生的情况施加任何要求——它没有被指定为您的程序中的错误,也不是编译器需要将您的程序视为不正确而拒绝。 编译器也不需要拒绝您的程序。
有一种替代方法可以避免此问题:您可以省略#include <stdio.h>
而是自己声明printf
(以及您使用的<stdio.h>
中的任何其他函数)。 C 标准明确允许这样做,然后您可以为scanf
自由定义宏。
这是 C 标准的典型特征:它不会阻止您做可能导致问题的事情。 特别是,它不需要编译器警告您。 至少有三个原因(好或坏)C 标准是这样设计的:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.