为什么这个独立程序会出现段错误?

Del*_*ltA 3 c++

我发现了一个我无法解释的有趣行为。我编写了这个非常简单的程序,它在没有明显原因的情况下出现了段错误。请问,有人可以解释一下这里发生了什么吗?

  • 该程序在 Ubuntu 中运行(我不知道这是否重要)。
  • 没有包含,没有库,没有到 stdlib 的链接。没有任何依赖关系。

我已经测试过,当发生以下任何一种情况时,段错误就会消失:

  • stdlib 已链接(并重命名_startmain、删除了 extern "C" 等)
  • 使用海湾合作委员会
  • 优化已启用

以下是该程序唯一的代码文件,我们称之为main.cpp.

构建它clang main.cpp -nostdlib

struct A
{
    A () = default;
    A (const A &) = default;
    // A (A &) = default;

    char * a = nullptr;
    unsigned long long b;
};

struct ConvertibleToA
{
    ConvertibleToA() = default; // default constructor
    operator A() { return m_a; } // conversion to type A
    A m_a;
};

extern "C"
void _start()
{
    ConvertibleToA my_convertible{};
    A my_a = my_convertible;
}
Run Code Online (Sandbox Code Playgroud)

Eld*_*Bug 5

检查堆栈对齐情况。对于 SysV ABI,rsp保证在程序入口处 16 字节对齐。rsp然而,由于 .push 的地址,正常的函数期望是 16 字节 + 8 对齐call

Clang 使用 SSE 对齐指令,这会崩溃,而 GCC 不会。