C 角例和陷阱

发布于 2024-09-17 17:50:09 字数 148 浏览 5 评论 0原文

我很惊讶为什么这有效?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

能怎样 2024-09-24 17:50:09

显然,链接器不知道全局对象的类型(例如:变量或函数),而只知道地址;所以它链接程序就像你的变量是一个函数一样。由于明显的原因而崩溃。

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.

花桑 2024-09-24 17:50:09

你遇到这样的错误吗?

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

这不是编译器错误,而是链接器错误。

在编译过程中,每个源文件都被翻译为目标文件。

不检查 int main() 是否存在,因为程序可能由多个源组成,并且 main() 仅在其中一个源中定义,或者不存在。甚至不需要存在(例如在动态库中)。由于编译器将源

short main[] = {};

视为有效声明(创建名为 main 的全局 short 数组并初始化为空数组),因此不会生成任何错误。

int main() 是否存在的检测由链接器检查。链接器将编译后的目标文件绑定到工作可执行文件。如果链接器找不到符号main,它会像我上面描述的那样抱怨。不幸的是,传统的 C ABI 不区分函数或导出变量的类型。因此,即使 main 被声明为数组,由于链接器只知道“存在名为 main 的东西”而无法检查更多内容,因此它也会通过。

结果是程序虽然写错了,但生成时没有错误。

当程序运行时,所谓的main不保存可执行代码。相反,它只是一些数据(可能已归零)。所以系统可能会做任何意想不到的事情(在你的例子中,它是一个SEGFAULT)。

这实际上可以在使用 gcc 中的 -Wall 标志进行编译时捕获,并给出警告:

<stdin>:1: warning: ‘main’ is usually a function

Are you getting error like this?

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

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 the main() is only defined in one of these, or it doesn't even need to exist (e.g. in a dynamic library). Since the source

short main[] = {};

is considered a valid declaration (create a global short array named main 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 symbol main, 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 the main is declared as an array, since the linker only knows "something called main 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:

<stdin>:1: warning: ‘main’ is usually a function
国粹 2024-09-24 17:50:09

尝试使用更多选项进行编译。 :)

例如添加简单的 -Wall

gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function

我还没有阅读相关的标准页面,但显然你只需要有某种 main 才能编译,不一定是一个函数......

Try compiling with more options. :)

For example adding simple -Wall

gcc -Wall test.c -o t
test.c:1: warning: ‘main’ is usually a function

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文