c++ 堆栈顺序断言?

问题描述 投票:0回答:2

以下代码是否在每个兼容的编译器优化下都断言返回值

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";
}

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

c++ arrays stack indexoutofboundsexception
2个回答
3
投票

很多人已经在评论中指出您的代码目前有未定义的行为。

就排序而言,您可以保证,正如您现在定义的那样,

x
y
是有序的——也就是说,
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";
}

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


2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.