正在创建对不存在的数组项未定义行为的引用

Is creating a reference to a nonexistant array item undefined behavior?

本文关键字:未定义 引用 数组 创建 不存在      更新时间:2023-10-16

至少在我的编译器中,创建引用意味着不取消引用。因此,代码如下所示:

int trivialExample(char* array, int length)
{
    char& ref = array[6];
    if (length > 6)
    {
        std::cout << ref << std::endl;
    }
}

也就是说,给定一个char数组及其长度(假设数组元素等一堆琐事都已初始化,并且传递的长度是正确的(,只有当它确实存在时,它才会打印第七个字符。

这是基于未定义的行为吗?

实际上,这在概念上(实际上(与以下内容没有什么不同:

int trivialExample(char* array, int length)
{
    char *ptr = &array[6];
    if (length > 6)
    {
        std::cout << (*ptr) << std::endl;
    }
}

我有根据的猜测是,你打算这样称呼它:

char buffer[4];
trivialExample(buffer, sizeof(buffer));

在C++中,就像在C中一样,只要获得一个指向声明数组外部的指针(而不是倒数第二个(,就会调用未定义的行为,即使没有取消引用。

其原理是,可能存在仅通过在CPU寄存器中加载无效地址而发生故障的体系结构。

UPDATE:经过一些研究和其他SO用户的提示,我确信C++不允许在声明对象之外引用,甚至不允许引用倒数第二个元素。在这种特定的情况下,除了元素编号6之外,结果是相同的,这在指针版本中是允许的,而在引用版本中是不允许的。

行为未定义。

引用C++2003标准(ISO/IEC 14882:2003(E((,8.3.2第4段:

引用应初始化为引用有效对象或作用

这也意味着,初始化一个刚好超过数组末尾的引用是未定义的行为,因为那里没有有效的对象。

char& ref = array[6];

只要array的大小是最小7,这是可以的。否则,它是未定义的行为(UB(。

std::cout << ref << std::endl;

只要array[6]被初始化或分配了一些值,这是可以的。否则就是UB。

我不知道如何创建引用,但访问数组边界之外的元素是未定义的行为。因此,是的,您的代码依赖于未定义的行为。

不,这不是未定义的行为。这就像定义一个指针。引用是一个语法更友好、不易出错的指针。