为什么 mi 代码在 SSE2 中编译正常,但在 ARM无 NEON中编译不正常?

问题描述

好吧,这就是问题所在:我试图在 ARM 中编译我的 altoin,但出现堆栈粉碎错误:。中止。然后,我尝试在我的另一台 linux 计算机中编译完全相同的代码,但使用 SSE2 标志,并且它成功了。如果我在能够编译的 makefile 上禁用堆栈保护。但禁用它不是个好主意。我尝试使用较旧的 GCC,但没有什么是一样的。我的问题是,为什么我可以在 SSE2 指令中编译,而在 ARM 中不能? 这是在构建日志上创建警告的代码

double GaussianQuad_N(double func(const double),const double a2,const double b2,int NptGQ)
{
    double s = 0.0;
    double x[NptGQ],w[NptGQ];

    gauleg(a2,b2,x,w,NptGQ);
    for (int j = 1 ; j <= NptGQ ; j++)
        s += w[j] * func(x[j]);

    return s;
}

我明白了:

警告:堆栈保护器不保护局部变量:可变长度缓冲区 [-Wstack-protecto] double GaussianQuad_N(double func(const double)

解决方法

double x[NptGQ],w[NptGQ]; 变长数组在 C++ 中不是标准的。在 C++ 中使用 std::vector

std::vector<double> x(NptGQ),w(NptGQ);
gauleg(a2,b2,x.data(),w.data(),NptGQ);
,

您的数组的大小为 NptGQ,这意味着有效索引为 0 到 NptGQ-1。但是,您的循环从 1 到 NptGQ,因此最后一次迭代将超出数组的末尾。

像这样从数组的末尾运行会导致未定义的行为——它可能会起作用(如果数组后面的空间中没有任何重要的东西),或者它可能会崩溃或以其他方式行为不端。