C语言宏中的函数定义
此代码抛出一个错误,表示“代码未被引用” 这段代码运行也很顺利C语言宏中的函数定义,c,macros,C,Macros,此代码抛出一个错误,表示“代码未被引用” 这段代码运行也很顺利 #include<stdio.h> #define MAIN() m##a##i##n int main() { MAIN(); printf("C program"); return 0; } int code() { printf("C is life"); } #include <stdio.h> #define macro(n, a, i, m) m##a##i##n
#include<stdio.h>
#define MAIN() m##a##i##n
int main()
{
MAIN();
printf("C program");
return 0;
}
int code()
{
printf("C is life");
}
#include <stdio.h>
#define macro(n, a, i, m) m##a##i##n
#define MAIN macro(n, a, i, m)
int MAIN()
{
printf("C is life");
return 0;
}
在第一个代码中,为什么代码不像main那样工作?我不知道宏完成连接“main”后的过程是什么。请简单解释这些代码背后的过程。提前谢谢
我还尝试定义代码函数
#include<stdio.h>
#define MAIN() c##o##d##e
int code(void);
int main()
{
MAIN();
printf("C program");
return 0;
}
int code(void)
{
printf("C is life\n");
return 0;
}
因此,定义函数不应该是问题所在。我的问题是,连接后会发生什么?提前谢谢 在C中,您必须在任何调用之前定义函数的原型
int code()
:
int code (void);
函数main
是在汇编代码中声明的,这就是为什么您的第二个版本可以正确编译et
如果要避免此错误,请添加
-Wmissing prototype
编译标志,以便编译器检查您的函数是否有原型。问题是编译main()
时,code()
函数尚未声明
在main()之前移动code()
:
在C语言中(自C99标准以来),您需要在使用所有函数之前声明它们
在第一个示例中,您在尝试使用code
函数之前没有声明它。您可以通过添加函数原型来解决此问题:
第二个示例之所以有效,是因为您使用的是main
,此时已经声明了它。如果函数以前没有声明过,那么定义也会声明该函数
还请注意,展开后的宏实际上并不调用code
(或main
)函数。这很好,因为递归(直接或间接)调用main
通常是不好的。请记住宏在预处理器
阶段本身被替换。在C
中,每个函数在使用/调用之前都需要进行原型化,以便编译器提前知道它的参数
和返回类型
,以避免冲突
案例1:-当执行下面的代码块时,宏名MAIN()
被替换为code
#define MAIN() c##o##d##e
int main(){
MAIN();
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
在预处理器阶段之后,它如下所示
int main(){
code; /* errorenous statement */
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
观察行<代码>代码
在上述代码块中,它会导致编译错误。当您运行上面的代码时,如gcc-Wall-Wstrict prototype-Werror test.c
,它将警告
转换为错误
错误:“代码”未声明(首次在此函数中使用)#define MAIN()
c#o#d#e
^
要解决此问题,请像前面一样声明code()
\define
int code(void); /* declaration */
还有一个警告转换为错误
错误:语句无效[-Werror=unused value]#define MAIN()
c#o#d#e
因为宏替换后,它看起来像code代码>这里是上面的语句,没有任何效果。所以为了避免这种情况
将宏名称从MAIN()
更改为MAIN
。例如
#define MAIN c##o##d##e
案例1代码的正确版本
#include<stdio.h>
int code(void);
#define MAIN c##o##d##e
int main(void){
MAIN();
printf("C program");
return 0;
}
int code(void){
printf("C is life");
return 0;
}
案例2:-当执行下面的代码时,宏名MAIN()
将替换为MAIN
#define MAIN() m##a##i##n
int main(){
MAIN();
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
它看起来像是在预处理器阶段
int main(){
main; /* it causes error */
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
案例3:-当执行下面的代码块时,宏名MAIN()
被替换为code
&这里您也声明了code()
#define MAIN() c##o##d##e
int code(void);
int main() {
MAIN();
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
在预处理器阶段之后,它如下所示
int code(void);
int main() {
code;/* error causing statement */
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
建议您使用
gcc -Wall -Wstrict-prototypes -Werror test.c
因此,通过将警告转换为错误,您将了解更多 显然,它应该是#define MAIN(m,a,i,n)int m#a#i#n();m#a#i#n()
和MAIN(c,o,d,e)代码>。根据我需要的澄清,我现在已经很清楚地编辑了这个问题。MAIN()
在第一种情况下被替换为code
,而不是code()
。在第二种情况下,它被替换为main
,而不是main()
@Peter我修改了我的答案,以进一步澄清OP问题。请看一看。您可能想解释一下MAIN()
扩展为code
,而不是code()
,因此实际上不调用函数code()
。
#define MAIN c##o##d##e
#include<stdio.h>
int code(void);
#define MAIN c##o##d##e
int main(void){
MAIN();
printf("C program");
return 0;
}
int code(void){
printf("C is life");
return 0;
}
C is lifeC program
#define MAIN() m##a##i##n
int main(){
MAIN();
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
int main(){
main; /* it causes error */
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
#define MAIN() c##o##d##e
int code(void);
int main() {
MAIN();
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
int code(void);
int main() {
code;/* error causing statement */
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
gcc -Wall -Wstrict-prototypes -Werror test.c