最短的C程序,仍然会导致segfault

最短的C程序,仍然会导致segfault,c,gcc,segmentation-fault,C,Gcc,Segmentation Fault,有一段时间,我为自己编写了可能是我的第一个C无bug程序而感到非常自豪。 以下是完整的源代码: int main; 即使没有-int,它也能完美地编译,但会发出警告(即使没有-Wall),作为一个瞄准无bug程序的程序员,我将它们视为错误 在愉快地编译了这个应用程序之后,我立即启动了它。令我惊讶的是,出现了一个分段错误 现在说真的到底发生了什么事? 我的猜测如下:这是因为缺少main的定义。这是显而易见的,但编译器允许这样做。好的,main可以用不同的单位定义。但即使是链接器也没有做任何事情

有一段时间,我为自己编写了可能是我的第一个C无bug程序而感到非常自豪。 以下是完整的源代码:

int main;
即使没有
-int
,它也能完美地编译,但会发出警告(即使没有
-Wall
),作为一个瞄准无bug程序的程序员,我将它们视为错误

在愉快地编译了这个应用程序之后,我立即启动了它。令我惊讶的是,出现了一个分段错误


现在说真的到底发生了什么事?


我的猜测如下:这是因为缺少
main
的定义。这是显而易见的,但编译器允许这样做。好的,
main
可以用不同的单位定义。但即使是链接器也没有做任何事情。有什么特别的原因吗?

单词
main
是任何变量的法定名称。典型的用例是向编译器提供一个名为
main
的函数,编译器将其编译成一个对象文件,该文件又通过
crt0.o
链接到该文件,该文件为运行时(堆栈分配等)提供初始化,并跳转到标签
main

在C对象文件中,符号与原型无关,链接器成功链接了一个全局变量
int main作为要跳转到的主程序。然而,这个程序是垃圾。它很可能初始化为零,但很快处理器就会遇到一条随机指令,该指令访问程序分配的数据空间(堆栈+堆)之外的内存,或者指令流达到保留代码空间的限制

两者都会导致分段错误。实际上,如果系统运行在具有执行标志的体系结构上,则程序在第一次尝试跳转到数据段或页面时会在没有执行权限的情况下出错


进一步阅读以支持评论中的讨论:,

我认为问题在于您只定义了原型,而不是函数本身,等等:您只定义了一个变量,没有函数。到目前为止,还没有定义入口点。这可能会有所帮助。这取决于编译程序的方式和位置。托管环境程序需要一个
main
,但独立环境程序不需要。关于警告:
gcc-Wall-g-o main.c
给我
main.c:1:警告:“main”通常是一个函数(使用
gcc(Debian 4.4.5-8)4.4.5
)@dcorder(或原始海报)应该引用链接的解释作为这个问题的答案。我想在MS-DOS时代,可以编写一个工作
char main=0xc3try
常量字符main=0xc3右侧,甚至
const main=195在x64 Ubuntu上工作。关键是
const
数组/字符串以.text段的顺序编译,以便使用
mov标签[%rip],%rax
范例来达到,这是x64中加载64位常量的最短机器代码序列。回答很好。我只希望在完成时附上一些参考资料(例如关于数据执行预防)。只是为了完整。reddit线程可能很有用。