【问题标题】:Segmentation fault after returning an aligned structure返回对齐结构后的分段错误
【发布时间】:2015-12-22 17:14:44
【问题描述】:

我提出的问题的最小实例如下:

struct __attribute__((aligned(16))) Foo {
    float x, y, z;
    Foo(float x, float y, float z) : x(x), y(y), z(z) {}
};

class Bar {
public:
    Foo foo;

    Bar(const Foo &foo) : foo(foo) {}
    Foo bar() { return foo; }
};

int main()
{
    Bar *bar = new Bar(Foo(0.0f, 0.0f, 0.0f));
    bar->bar();
    return 0;
}

如果使用clang++(版本 3.4,Ubuntu 14.04 中的默认版本)编译,这段代码在运行时会导致分段错误。当我使用g++(4.8.4 版)编译它时,不会出现问题。这是编译器错误还是我的代码有问题?

附带说明:如果bar 是堆栈分配的,则程序不会崩溃,即:

Bar bar(Foo(0.0f, 0.0f, 0.0f));
bar.bar();

按预期工作。

【问题讨论】:

  • 退出前delete bar;有什么不同吗?
  • @BarışUşaklı:不。问题恰恰出在return foo; 语句上。例如,如果我将其替换为return Foo(0.0f, 0.0f, 0.0f);,问题就消失了。
  • 在适当的错误网站上将其作为错误提出?这不是错误报告场所。
  • 用 std::alignas 试过了吗?
  • 查看生成的 asm 代码可能会提供一些见解。据我了解,它看起来像一个编译器错误。但我不是语言律师,所以我不能确定这是一个编译器错误。如果我们忽略了一些语言模糊,生成的代码可能会提供提示以查看我们忽略的内容。

标签: c++ segmentation-fault g++ clang


【解决方案1】:

我猜这个基于堆栈的版本很幸运可以对齐。在指令之前添加一个 U8 可以使堆栈不同,以便您可以对其进行测试。 当你把它放在堆上时,它会变得随机:-) 您有可能在代码生成中遇到错误,因为您的 32 位值可能在 16 位边界上对齐,并且已为未对齐的访问生成代码。 X86 会默默地处理这个异常,但不会处理浮点数。这也值得尝试 - 更改为整数。

【讨论】:

    猜你喜欢
    • 2011-03-23
    • 2023-03-17
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多