main;
而已。
真的。
本质上,它的作用是将其定义main
为一个变量。在C语言中,变量和函数都是符号——内存中的指针,所以编译器不区分它们,这段代码也不会抛出错误。
但是,问题在于系统如何运行可执行文件。简而言之,C 标准要求所有 C 可执行文件都内置一个环境准备入口点,这基本上归结为“调用main
”。
然而,在这种特殊情况下,main
是一个变量,因此它被放置在一个名为 的非可执行内存部分中.bss
,用于变量(而不是.text
代码)。尝试执行代码.bss
违反了其特定的分段,因此系统抛出分段错误。
为了说明,这里是结果文件的(部分)objdump
:
# (unimportant)
Disassembly of section .text:
0000000000001020 <_start>:
1020: f3 0f 1e fa endbr64
1024: 31 ed xor %ebp,%ebp
1026: 49 89 d1 mov %rdx,%r9
1029: 5e pop %rsi
102a: 48 89 e2 mov %rsp,%rdx
102d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
1031: 50 push %rax
1032: 54 push %rsp
1033: 4c 8d 05 56 01 00 00 lea 0x156(%rip),%r8 # 1190 <__libc_csu_fini>
103a: 48 8d 0d df 00 00 00 lea 0xdf(%rip),%rcx # 1120 <__libc_csu_init>
# This is where the program should call main
1041: 48 8d 3d e4 2f 00 00 lea 0x2fe4(%rip),%rdi # 402c <main>
1048: ff 15 92 2f 00 00 callq *0x2f92(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5>
104e: f4 hlt
104f: 90 nop
# (nice things we still don't care about)
Disassembly of section .data:
0000000000004018 <__data_start>:
...
0000000000004020 <__dso_handle>:
4020: 20 40 00 and %al,0x0(%rax)
4023: 00 00 add %al,(%rax)
4025: 00 00 add %al,(%rax)
...
Disassembly of section .bss:
0000000000004028 <__bss_start>:
4028: 00 00 add %al,(%rax)
...
# main is in .bss (variables) instead of .text (code)
000000000000402c <main>:
402c: 00 00 add %al,(%rax)
...
# aaand that's it!
PS:如果您编译为平面可执行文件,这将不起作用。相反,您将导致未定义的行为。