在上一讲的笔记中,符号解析过程已经说过,符号解析会维护一个未解析的符号集合U,当时说感觉U一开始会把main给加进去,这里进行验证。
Part1
1.没有main的情况
int a=2;
int money()
{
int b=1;
return 0;
}
这个报错了,因为没有main的定义。
2.有一个main全局变量但没有main函数的情况
int main=520;
int money()
{
int temp=1;
return 0;
}
这个在编译链接都没有出错,说明确实是U里面会等待一个main,而这个main无论是全局变量还是函数,都是一样的,因而当看到一个main的符号定义时,就在U中移除main这个符号,因而不会报错,且,这表明变量和函数是一样的符号,但是我记得变量和函数名是不一样的,而且不同参数类型,返回值的函数也是不一样的,这里有个疑问,因而埋个坑到Part2去分析。
3.有一个main局部变量但没有main函数的情况
int money()
{
int main=520;
int temp=1;
return 0;
}
这个报错在意料之中。
4.
// hello.c
int money()
{
main();
return 0;
}
// main.c
int main()
{
printf("main.c is called!\n");
}
这个报错,因为没有头文件stdio.h,这里埋一个坑,为什么用函数必须要先声明(头文件作用应该就是声明吧主要),在Part3中予以分析。
5.
// hello.c
int money()
{
main();
return 0;
}
// main.c
#include <stdio.h>
int main()
{
printf("main.c is called!\n");
}
报错:
这里说main没有声明,那么在hello.c中加入main的声明试试。
// hello.c
int main();
int money()
{
main();
return 0;
}
// main.c
#include <stdio.h>
int main()
{
printf("main.c is called!\n");
}
改了声明就可以了。
6.
// hello.c
#include <stdio.h>
int main();
int money()
{
printf("hello.c is called!\n");
main();
return 0;
}
// main.c
#include <stdio.h>
int main()
{
printf("main.c is called!\n");
return 0;
}
这里的结果非常有意思。
怎么都是只进入main.c,这里的理由应该是,U=main.c,在hello.c中没有找到main符号的定义,所以就去main.c找,把hello.c扔了,在那找到了,然后运行,下面试验:
// hello.c
#include <stdio.h>
int money()
{
printf ("hello.c is called!\n");
}
// main.c
#include <stdio.h>
int main()
{
printf("main.c is called!\n");
return 0;
}
果然是这样!所以符号解析感觉就像是栈一样,U同一时刻只能有一个,然后就奔着这个符号去找。至于为什么5会出错,和这个不是同一个原因,那个是但凡里面有函数调用,必须要先有函数声明,无论这个模块是否会真正运行都一样,这个感觉是一个类似编译检查,下面这个图片验证了果然是这样。
分析了这么多,结论就是,U一开始有一个main,所以一定会先去找main在哪,如果没有main就扔掉这个.o或者.a,直到找到main为止。如果main不再调用别的,结束。如果还调用,那么同样的一直找。直到找完了或者不再调用了为止,找完了还是U中有东西的话,就报错!!!