3

我很惊讶为什么这有效?

short main [] ={};

这是文件中唯一的内容。它在 gcc 上正确编译。但是当我运行它时会打印分段错误。当我重命名 main 时,编译器会出错。谁能解释一下这里发生了什么。

4

3 回答 3

4

显然链接器不知道全局对象的类型(例如:变量或函数),而只知道地址;因此它将程序链接起来,就好像您的变量是一个函数一样。由于明显的原因而崩溃。

于 2010-09-01T13:05:47.377 回答
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)。

这实际上可以在使用-Wallgcc 中的标志编译时被捕获,这会给出警告:

<stdin>:1: warning: ‘main’ is usually a function
于 2010-09-01T13:15:10.360 回答
1

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

例如添加简单的 -Wall

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

我没有阅读相关的标准页面,但显然你只需要拥有某种 main 才能编译,不一定是函数......

于 2010-09-01T13:09:07.677 回答