问题描述
我正在尝试重命名“ stdio.h”函数或至少为其命名一个别名。我尝试过:
#include <stdio.h>
#define printf() test()
int main() {
teste("Hello World!\n");
return 0;
}
但没有成功,我也尝试下载stdio.h源代码并对其进行编辑,但是它收到了太多警告,并且未按预期运行。
解决方法
您需要先放置宏名称,然后删除括号:
#define test printf
或者,如果您需要括号和参数:
#define test(...) printf(__VA_ARGS__);
请注意,此类宏仅对测试代码功能“模拟”有意义。仅出于此目的而重命名,或者为了创建自己的“秘密宏语言”而重命名是非常糟糕的做法。
,这个想法是基于printf()定义一个宏。这是定义自制调试/日志服务的常用方法。
有一些陷阱需要避免:
- 请勿放置“;”在宏的末尾,否则您可能会面临 在“ if / else”语句中使用宏并将您放置在 终止的“;”在宏之后:
#define test(...) printf(__VA_ARGS__);
int main(void)
{
if (1)
test("message 1\n");
else
test("message 2\n");
return 0;
}
编译器将显示如下错误:'else' without a previous 'if'
因此,最好在定义宏时不以“;”结尾:
#define test(...) printf(__VA_ARGS__)
- 强制使用格式字符串,否则将出现以下错误:
#define test(...) printf(__VA_ARGS__)
int main(void)
{
char *str = "foo%bar";
test(str);
return 0;
}
编译器将发出警告:format not a string literal and no format arguments [-Wformat-security]
,因为字符串中有一个“%”。
因此,最好将宏定义为:
#define test(format,...) printf(format,__VA_ARGS__)
int main(void)
{
char *str = "foo%bar";
test("%s",str);
return 0;
}
- 但是如果您要打印不带任何格式说明符的字符串,例如:
#define test(format,__VA_ARGS__)
int main(void)
{
test("A string without format specifiers\n");
return 0;
}
由于变量部分(即__VA_ARGS__
)为空,因此编译器将引发错误:
error: expected expression before ')' token
6 | #define test(format,__VA_ARGS__)
为防止这种情况,可以使用预处理器“ ##”技巧(它是GCC特定的扩展名):
#define test(format,##__VA_ARGS__)
int main(void)
{
test("A string without format specifiers\n");
return 0;
}
- 当然,由于宏使用对服务函数(
printf()
的调用,因此请包含定义宏的相应头文件(<stdio.h>
):
#include <stdio.h>
#define test(format,##__VA_ARGS__)
int main(void)
{
test("A string without format specifiers\n");
return 0;
}
最后,为避免在使用C语言编写宏时避免所有前面的陷阱以及许多其他陷阱,我可以建议Best practices for the C language preprocessor