C角箱和陷阱

时间:2010-09-01 13:03:10

标签: c platform-specific

我很惊讶为什么会这样?

short main [] ={};

这是文件中的唯一内容。它在gcc上正确编译。但是,当我运行它打印分段故障。当我重命名main时,编译器会出错。 任何人都可以向我解释这里发生了什么。

3 个答案:

答案 0 :(得分:4)

显然链接器不知道全局对象的类型(如:变量或函数),而只知道地址;所以它将程序链接就好像你的变量是一个函数一样。因显而易见的原因崩溃了。

答案 1 :(得分:3)

你得到这样的错误吗?

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

这不是编译器错误,而是链接器错误。

在编译中,每个源文件都被转换为目标文件。

没有检查int main()是否存在,因为程序可能包含多个来源,而main()仅在其中一个中定义,或者甚至不需要存在(例如,动态库)。自源

short main[] = {};

被认为是一个有效的声明(创建一个名为short的全局main数组并初始化为空数组),它不会产生任何错误。

链接器检查是否存在int main()的检测。链接器将编译的目标文件绑定到工作的可执行文件。如果链接器找不到符号main,它会像我上面描述的那样抱怨。遗憾的是,传统的C ABI不区分函数或类型的导出变量。因此,即使将main声明为数组,由于链接器只知道“存在main存在的东西”并且无法检查更多,它也会通过。

结果是程序生成没有错误,尽管写错了。

当程序运行时,所谓的main不包含可执行代码。相反,它只是一些数据(可能是零)。所以系统可能会做任何意外的事情(在你的情况下,它是一个SEGFAULT)。

在使用gcc中的-Wall标志进行编译时,实际上可以捕获到这一点,这会发出警告:

<stdin>:1: warning: ‘main’ is usually a function

答案 2 :(得分:1)

尝试使用更多选项进行编译。 :)

例如添加简单的-Wall

gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function

我没有阅读相关的标准页面,但显然你只需要有一些主要的编译,不一定是函数......