c++堆栈顺序是否Assert?

iqxoj9l9  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(145)

下面的代码在每个兼容的编译器优化下都Assert返回值14吗?这是值得推荐的吗?这比在一个公共数组上引入两个指针更有效吗?下面的堆栈技术有具体的名称吗?在合理或令人钦佩的假设下,哪个更好的实践在编译时产生完全相同的二进制文件?

#include <iostream>

class A{
public:
    double x[10];
    double y[10];
};

int main(){
    A a;
    a.y[3] = 14;
    std::cout << a.x[13] << "\n";
}

我在哪里可以找到这样的测定?(链接,参考)。我想有一个技巧来有效地阅读标准。

4ioopgfo

4ioopgfo1#

许多人已经在评论中指出,您的代码当前具有未定义的行为。
就排序而言,可以保证xy是有序的--也就是说,y的内存地址比x高。但它们之间可能有填充,因此重叠比预期的要少,或者根本没有重叠。此外,该标准允许(但不是必需的)可以检查数组索引的有效性,因此,即使它们彼此紧邻,也允许编译器检查,因为您定义x具有10个元素,所以任何索引超过第10个元素的尝试都将失败(例如,导致硬件中断或故障)。
这就留下了一个问题,即如何获得你显然想要的结果,但具有定义的行为。你有几个选择。一个是分配一个数组,并添加一个别名,允许你将它的一半视为一个单独的数组:

#include<iostream>

class A{
public:
    double x[20];
    double *y = &x[10];
};

int main(){
    A a;
    a.y[3] = 14;
    std::cout << a.x[13] << "\n";
}

另一种方法是将两个阵列分开,但添加一个小代理,允许将两个阵列作为一个阵列进行寻址:

#include<iostream>

class proxy {
    double *x_;
    size_t N;
    double *y_;
public:
    template <class T, std::size_t N>
    proxy(T (&x_)[N], T *y) : x_(x_), N(N), y_(y) {}

    double &operator[](std::size_t n) {
        if (n < N)
            return x_[n];
        else
            return y_[n-N];
    }
};

class A{
    double x_[10];
public:
    double y[10];
    proxy x{x_, y};
};

int main(){
    A a;
    a.y[3] = 14;
    std::cout << a.x[13] << "\n";
}

除非你真的需要为这两个项目使用单独的数组,否则第一个可能更好--它显然更简单,而且可能更快。

cqoc49vn

cqoc49vn2#

这是未定义的行为。你不能保证数组之间没有填充。

相关问题