我很惊讶,为什么这个工程?C角箱和陷阱
short main [] ={};
这是文件中唯一的内容。它在gcc上正确编译。但是,当我运行它打印分段错误。当我重命名主,编译器给出错误。 任何人都可以解释我在这里发生了什么。
我很惊讶,为什么这个工程?C角箱和陷阱
short main [] ={};
这是文件中唯一的内容。它在gcc上正确编译。但是,当我运行它打印分段错误。当我重命名主,编译器给出错误。 任何人都可以解释我在这里发生了什么。
显然,链接器不知道全局对象的类型(如:变量或函数),但只有地址;所以它将程序链接起来,就好像你的变量是一个函数一样。出于显而易见的原因,这崩溃了。
尝试使用更多选项编译。 :)
例如添加简单-Wall
gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function
我没有看到相关的标准页,但显然你就必须有主某种以编译,不一定是功能.. 。
'gcc -ansi -pedantic -W -Wall' – 2010-09-01 13:16:23
你是否得到这样的错误?
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)。与-Wall
标志GCC,这给出了一个警告,编译时
这实际上可以被捕获:
<stdin>:1: warning: ‘main’ is usually a function
我相信,我已经看到了这一个已经,您声明外部符号主要和连接器没有按不关心类型。这是不正确的C. – jbcreix 2010-09-01 13:06:28
-1对于问题为什么一些有未定义行为的荒谬代码“起作用”(在一个非常不好的意义上,不会更少)。 – 2010-09-01 13:18:05
我想有人应该提到这个[IOCCC entry](http://www.ioccc.org/years.html#1984_mullender)。 – 2010-09-01 13:30:44