为什么const int的主要= 195结果在一个工作计划,但没有它在分割故障结束常量? [英] Why does const int main = 195 result in a working program but without the const it ends in a segmentation fault?

查看:123
本文介绍了为什么const int的主要= 195结果在一个工作计划,但没有它在分割故障结束常量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的C程序(见现场演示这里)。

  const int的主要= 195;

我知道,在现实世界中没有程序员编写code这样的,因为它没有用处,并没有任何意义。但是,当我删除从它立刻导致分割上面的程序常量关键字故障。为什么?我急切地想知道这背后的原因。

GCC 4.8.2编译给人当它下面的警告。


  

警告:'主'通常是一个函数[-Wmain]

  const int的主要= 195;
          ^


为什么常量的presence和缺乏关键字有所作为这里的程序的行为?


解决方案

观察值195如何对应于8086兼容的 RET (返回从功能)指令。这个定义这样的行为,如果你将它定义为 INT的main(){} 执行时。

在某些平台上,常量数据加载到一个可执行但不可写的内存区域,而可变数据(即数据没有资格常量)被装入一个可写的,但不能执行存储区域。出于这个原因,该计划作品当你声明常量而不是当你离开离开常量预选赛。

传统的二进制文件包含了三个的部分:


  • 文本段(如果该架构支持)写保护和可执行文件,包含可执行code,中的静态存储时间限定常量和字符串文字

  • 数据段可写,不能执行。它包含变量没有资格常量静态的存储时间和(在运行时)使用的分配的存储时间
  • BSS 段类似于数据段,但被初始化为全零。它包含的变量的静态的存储期没有资格常量已宣告没有初始化

  • 段不是二进制present并包含变量的自动的存储时间

删除常量与变量导致其从移动预选赛的文字数据段,这是不是可执行文件,造成分段违例你观察。

现代的平台上往往有进一步的细分(用于数据例如,一个 rodata 段既不是可写的,也没有可执行的),所以请不要把这个作​​为你的平台的准确描述没有咨询平台特定的文档。

请明白不是让函数通常是不正确,虽然在技术上的一个平台可以让是声明为一个变量,比照ISO 9899:2011§5.1.2.2.1¶1,重点煤矿:


  

1名为在程序启动时的功能被命名为。实施声明没有原型此功能。它应 INT 的返回类型和不带参数(...)或两个参数(...)或同等定义;或在其他一些实现定义的方式。


Consider following C program (see live demo here).

const int main = 195;

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 gives following warning when compiling it.

warning: 'main' is usually a function [-Wmain]

const int main = 195;
          ^

Why does the presence and absence of const keyword make a difference here in the behavior of the program?

解决方案

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.

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:

  • The text segment is (if supported by the architecture) write-protected and executable, and contains executable code, variables of static storage duration qualified const, and string literals
  • The data segment is writeable and cannot be executed. It contains variables not qualified const with static storage duration and (at runtime) objects with allocated storage duration
  • The bss segment is similar to the data segment but is initialized to all zeroes. It contains variables of static storage duration not qualified const that have been declared without an initializer
  • The stack segment is not present in the binary and contains variables with automatic storage duration

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.

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.

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 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 of int and with no parameters (...) or with two parameters (...) or equivalent; or in some other implementation-defined manner.

这篇关于为什么const int的主要= 195结果在一个工作计划,但没有它在分割故障结束常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆