开发者

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

开发者 https://www.devze.com 2023-04-09 15:52 出处:网络
With my compiler at least, creating a reference implies no dereferencing. Therefore, code like the following works:

With my compiler at least, creating a reference implies no dereferencing. Therefore, code like the following works:

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

That is, given a char array and its length (and assuming a bunch of trivialities like t开发者_如何学JAVAhe array elements are all initialized and the passed length is correct), it will print the seventh character only if it actually exists.

Is this relying on undefined behavior?


Actually, this is conceptually (and practically) not different than the following:

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

My educated guess is that you intend to call it this way:

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

And in C++, as in C, just obtaining a pointer to outside of the declared array (other than the next-to-last) invokes undefined behaviour, even if not dereferenced.

The rationale is that there may be (are?) architectures that faults just by loading an invalid address in a CPU register.

UPDATE: After some research, and hints from other SO users, I've becomed convinced that C++ does not allow to take a reference outside of the declaring object, not even to the next-to-last element. In this particular case, the results are the same, except for the element number 6, that would be allowed in the pointer version and not in the reference one.


The behavior is undefined.

Quoting from the C++ 2003 standard (ISO/IEC 14882:2003(E)), 8.3.2 paragraph 4:

A reference shall be initialized to refer to a valid object or function.

Which also implies that initializing a reference to just past the end of an array is undefined behavior, since there's no valid object there.


char& ref = array[6];

This is okay as long as the size of array is minimum 7. Otherwise it is undefined behavior (UB).

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

This is okay as long as array[6] is initialized or assigned with some value. Otherwise it is UB.


I don't know about creating references, but accessing an element outside the bounds of the array is undefined behavior. So yes, your code is relying on undefined behavior.


No, it is not undefined behavior. It is just like defining a pointer. A reference is a pointer with a friendlier and less error prone syntax.

0

精彩评论

暂无评论...
验证码 换一张
取 消