C 角例和陷阱
我很惊讶为什么这有效?
short main [] ={};
这是文件中的唯一内容。它在 gcc 上编译正确。但是当我运行时它会打印分段错误。当我重命名 main 时,编译器给出错误。 谁能解释一下这里发生了什么。
I am surprised why this works?
short main [] ={};
This is the only content in the file. It compiles correctly on gcc. But when i run it prints segmentation fault. When i rename main, compiler gives errors.
Can anyone explain me what is going on here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
显然,链接器不知道全局对象的类型(例如:变量或函数),而只知道地址;所以它链接程序就像你的变量是一个函数一样。由于明显的原因而崩溃。
Apparently the linker doesn't know the type of global objects (like: variable or function), but only the address; so it links the program as if your variable was a function. Which crashes for obvious reasons.
你遇到这样的错误吗?
这不是编译器错误,而是链接器错误。
在编译过程中,每个源文件都被翻译为目标文件。
不检查
int main()
是否存在,因为程序可能由多个源组成,并且main()
仅在其中一个源中定义,或者不存在。甚至不需要存在(例如在动态库中)。由于编译器将源视为有效声明(创建名为
main
的全局short
数组并初始化为空数组),因此不会生成任何错误。int main()
是否存在的检测由链接器检查。链接器将编译后的目标文件绑定到工作可执行文件。如果链接器找不到符号main
,它会像我上面描述的那样抱怨。不幸的是,传统的 C ABI 不区分函数或导出变量的类型。因此,即使main
被声明为数组,由于链接器只知道“存在名为main
的东西”而无法检查更多内容,因此它也会通过。结果是程序虽然写错了,但生成时没有错误。
当程序运行时,所谓的
main
不保存可执行代码。相反,它只是一些数据(可能已归零)。所以系统可能会做任何意想不到的事情(在你的例子中,它是一个SEGFAULT)。这实际上可以在使用 gcc 中的
-Wall
标志进行编译时捕获,并给出警告:Are you getting error like this?
This is not a compiler error, but a linker error.
In compilation, each source file is translated to an object file.
There is no check whether
int main()
exists because the program may consist of multiple sources, and themain()
is only defined in one of these, or it doesn't even need to exist (e.g. in a dynamic library). Since the sourceis considered a valid declaration (create a global
short
array namedmain
and initialize to an empty array) by the compiler, it will not generate any errors.The detection of whether
int main()
exists is checked by the linker. The linker binds the compiled object files to a working executable. If the linker cannot find the symbolmain
, it will complain like the one I described above. Unfortunately, the conventional C ABI does not differentiate between functions or or kinds of exported variables. So even if themain
is declared as an array, since the linker only knows "something calledmain
exists" and cannot check more, it will pass as well.The result is that the program is generated without error although it is wrongly written.
When the program is run, the so-called
main
does not hold executable code. Rather, it is just some data (likely zeroed). So the system may do anything unexpected (in your case, it is a SEGFAULT).This can actually be caught when compiling with the
-Wall
flag in gcc, which gives a warning:尝试使用更多选项进行编译。 :)
例如添加简单的 -Wall
我还没有阅读相关的标准页面,但显然你只需要有某种 main 才能编译,不一定是一个函数......
Try compiling with more options. :)
For example adding simple -Wall
I have not read the relevant standard page, but apparently you just have to have main of some kind in order to compile, not necessarily a function...