为什么 const int main = 195 会导致程序正常工作,但没有 const 会导致分段错误? [英] Why does const int main = 195 result in a working program but without the const it ends in a segmentation fault?
问题描述
考虑以下 C 程序(查看现场演示 此处).
Consider following C program (see live demo here).
const int main = 195;
我知道在现实世界中没有程序员编写这样的代码,因为它没有任何用处,也没有任何意义.但是,当我从程序上方删除 const
关键字时,它会立即导致 分段错误.为什么?我很想知道这背后的原因.
I know that in the real world no programmer writes code like this, because it serves no useful purpose and doesn't make any sense. But when I remove the const
keyword from above the program it immediately results in a segmentation fault. Why? I am eager to know the reason behind this.
GCC 4.8.2 在编译时给出以下警告.
GCC 4.8.2 gives following warning when compiling it.
警告:'main' 通常是一个函数 [-Wmain]
warning: 'main' is usually a function [-Wmain]
const int main = 195;
^
为什么 const
关键字的存在和不存在会对程序的行为产生影响?
Why does the presence and absence of const
keyword make a difference here in the behavior of the program?
推荐答案
观察值 195 如何对应 8086 兼容机上的 ret
(从函数返回)指令.因此,main
的定义就像您在执行时将其定义为 int main() {}
一样.
Observe how the value 195 corresponds to the ret
(return from function) instruction on 8086 compatibles. This definition of main
thus behaves as if you defined it as int main() {}
when executed.
在某些平台上,const
数据被加载到可执行但不可写的内存区域,而可变数据(即未限定 const
的数据)被加载到可写但不可写可执行内存区域.出于这个原因,当您将 main
声明为 const
时,程序工作",但当您离开 const
限定符时则不会.
On some platforms, const
data is loaded into an executable but not writeable memory region whereas mutable data (i.e. data not qualified const
) is loaded into a writeable but not executable memory region. For this reason, the program "works" when you declare main
as const
but not when you leave off the const
qualifier.
传统上,二进制文件包含三个段:
Traditionally, binaries contained three segments:
text
段(如果架构支持)写保护和可执行,并且包含可执行代码、static 存储持续时间限定的变量const
和字符串字面量data
段是可写的,不能执行.它包含未限定的变量const
具有 static 存储持续时间和(在运行时)具有 已分配 存储持续时间的对象bss
段类似于data
段,但初始化为全零.它包含 static 存储持续时间未限定的变量const
已在没有初始化程序的情况下声明stack
段不存在于二进制文件中,并且包含具有自动 存储持续时间的变量
- The
text
segment is (if supported by the architecture) write-protected and executable, and contains executable code, variables of static storage duration qualifiedconst
, and string literals - The
data
segment is writeable and cannot be executed. It contains variables not qualifiedconst
with static storage duration and (at runtime) objects with allocated storage duration - The
bss
segment is similar to thedata
segment but is initialized to all zeroes. It contains variables of static storage duration not qualifiedconst
that have been declared without an initializer - The
stack
segment is not present in the binary and contains variables with automatic storage duration
从变量 main
中删除 const
限定符会导致它从 text
移动到 data
段,这是不可执行的,导致您观察到分段违规.
Removing the const
qualifier from the variable main
causes it to be moved from the text
to the data
segment, which isn't executable, causing the segmentation violation you observe.
现代平台通常有更多段(例如,rodata
段用于既不可写也不可执行的数据),因此请不要在未查阅平台特定文档的情况下将其视为对您平台的准确描述.
Modern platforms often have further segments (e.g. a rodata
segment for data that is neither writeable nor executable) so please don't take this as an accurate description of your platform without consulting platform-specific documentation.
请理解,不将 main
设为函数通常是不正确的,尽管从技术上讲,平台可以允许将 main
声明为变量,参见.ISO 9899:2011 §5.1.2.2.1 ¶1,强调我的:
Please understand that not making main
a function is usually incorrect, although technically a platform could allow main
to be declared as a variable, cf. ISO 9899:2011 §5.1.2.2.1 ¶1, emphasis mine:
1 程序启动时调用的函数名为main
.实现没有声明这个函数的原型.它应定义为返回类型 int
且不带参数 (...) 或带两个参数 (...) 或等效项;或以其他实现定义的方式.
1 The function called at program startup is named
main
. The implementation declares no prototype for this function. It shall be defined with a return type ofint
and with no parameters (...) or with two parameters (...) or equivalent; or in some other implementation-defined manner.
这篇关于为什么 const int main = 195 会导致程序正常工作,但没有 const 会导致分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!