有一刻,我为自己编写了我可能的第一个无错误程序而感到非常自豪。 以下是完整的源代码:
int main;
即使没有int
,它也能完美编译,但会发出警告(即使没有-Wall
),并且作为一个针对无错误程序的程序员,我将它们视为错误。
我愉快地编写了这个应用程序,我立即赶紧启动它。令我惊讶的是,出现了分段错误错误......
现在认真。 到底发生了什么?
我的猜测如下:缺少main
的定义。这是如此明显,但编译器允许它。好的,main
可以在不同的单元中定义。但即使链接器也没有做任何事情。有什么特别的原因吗?
答案 0 :(得分:20)
单词main
是任何变量的合法名称。典型的用例是向编译器提供名称main
的函数,编译器将其编译为目标文件,而目标文件又与crt0.o
链接,为运行时提供初始化(堆栈)分配等)并跳转到标签main
。
在C对象文件中,符号与原型无关,链接器成功链接全局变量int main;
作为要跳转到的主程序。然而,这个程序是垃圾。它很可能初始化为零,但很快处理器遇到一个随机指令,它访问程序分配数据空间(堆栈+堆)之外的内存,或者指令流达到保留代码空间的限制。
两者都会导致分段错误。实际上,如果系统在具有执行标志的体系结构上运行,则程序会在第一次尝试跳转到 data 段或页面时进行段错误,而无需执行权限。
进一步阅读以支持评论中的讨论:Data Execute Prevention,NX_bit