设为首页 加入收藏

TOP

把C程序的int main(void)改成static int main(void)会怎样呢?(一)
2014-11-23 17:59:06 来源: 作者: 【 】 浏览:33
Tags:程序 int main void 改成 static 怎样
如题,把C程序中的主函数int main(void)改成static int main(void)会怎么样呢?
比如把
复制代码
#include
int main(void)
{
printf("Hi\n");
return 0;
}
复制代码
修改为:
复制代码
#include
static int main(void)
{
printf("Hi\n");
return 0;
}
复制代码
请读者先自己想一想!
————————————————————分割线———————————————————
这个问题是我在看static关键字的时候提出来的。
只要你了解static关键字会使标示符具有内部链接(Internel Linkage)属性,并且了解过C程序的编译链接流程,应该可以得出答案——
把C程序中的主函数int main(void)改成static int main(void)会导致链接失败。
可以验证一下:
[zhanghaiba@Fedora code]$ gcc static_int_main.c
/usr/lib/gcc/i686-redhat-linux/4.4.5/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
如果换成gcc -c呢?
[zhanghaiba@Fedora code]$ gcc -c static_int_main.c
[zhanghaiba@Fedora code]$
可见换成gcc -c可以编译成功,因为gcc -c只有预处理、编译和汇编阶段,没有链接阶段。
首先,我们要了解一下 Linux下GCC环境中C程序的编译链接流程——
编译C程序,一般包括了C预处理阶段、C到汇编的编译阶段、汇编到目标文件的编译阶段、目标文件的链接阶段。
GCC支持下面几个命令,使我们可以观察到这些阶段:
1)gcc -v GCC.c
编译时打印出总的编译流程,可以看到使用了哪些编译工具。v是verbose(冗长)的意思,即尽可能多的打印信息。
2) gcc -E GCC.c
把源文件用预处理器处理,可重定向输出到GCC.i文件再查看
3)gcc -S GCC.c
把源文件用预处理器和编译器处理,自动输出同名的GCC.s文件
4)gcc -c GCC.c
把源文件用预处理器、编译器和汇编器处理,自动输出同名.o文件
5)gcc GCC.c
把源文件用预处理器、编译器、汇编器处理后,最后使用链接器生成缺省名为a.out的可执行文件
为什么默认叫a.out?因为早期编译并没有链接器的概念,a.out是汇编器直接生成的,a意为assembly。但需要澄清的是在现代编译器中a.out都是由链接器生成。
另外,使用选项-save-temps可以保留中间生成的文件,示范如下:
[zhanghaiba@Fedora code]$ ls | grep hi
hi.c
hi.i
hi.o
hi.s
我们再用gcc -v来观察总的编译流程
复制代码
[zhanghaiba@Fedora code]$ gcc -v hi.c
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.5 20101112 (Red Hat 4.4.5-2) (GCC)
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=i686'
/usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet -v hi.c -quiet -dumpbase hi.c -mtune=generic -march=i686 -auxbase hi -version -o /tmp/ccrwAICf.s
ignoring nonexistent directory "/usr/lib/gcc/i686-redhat-linux/4.4.5/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/i686-redhat-linux/4.4.5/../../../../i686-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i686-redhat-linux/4.4.5/include
/usr/include
End of search list.
GNU C (GCC) version 4.4.5 20101112 (Red Hat 4.4.5-2) (i686-redha
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇[Objective-C]OC中自动释放池的基.. 下一篇[Objective-C]OC中代理(委托)设计..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: