Создает ли ссылка на несуществующий элемент массива неопределенное поведение? - PullRequest
3 голосов
/ 01 октября 2011

По крайней мере, с моим компилятором, создание ссылки не требует разыменования. Поэтому работает код, подобный следующему:

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

То есть, учитывая массив char и его длину (и предполагая, что куча тривиальностей, таких как элементы массива, все инициализированы и переданная длина верна), он напечатает седьмой символ, только если он действительно существует.

Это полагается на неопределенное поведение?

Ответы [ 5 ]

6 голосов
/ 01 октября 2011

На самом деле, это концептуально (и практически) не отличается от следующего:

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, простое получение указателя на внешнюю часть объявленного массива (кроме последнего к последнему) вызывает неопределенное поведение , даже если не разыменовано.

Обоснованиеможет ли быть (есть?) архитектура, которая дает сбой просто при загрузке неверного адреса в регистр ЦП.

ОБНОВЛЕНИЕ : После некоторых исследований и подсказок от других пользователей SO, я 'Мы убедились, что C ++ не позволяет брать ссылку вне объявленного объекта, даже на элемент, следующий за последним.В этом конкретном случае результаты совпадают, за исключением элемента номер 6, который был бы разрешен в версии указателя, а не в справочной версии.

2 голосов
/ 01 октября 2011

Поведение не определено.

Цитирование из стандарта C ++ 2003 (ISO / IEC 14882: 2003 (E)), пункт 8.3.2, пункт 4:

Ссылка должнабыть инициализированным для ссылки на действительный объект или функцию.

Что также подразумевает, что инициализация ссылки только после конца массива является неопределенным поведением, поскольку там нет действительного объекта.

1 голос
/ 01 октября 2011

Я не знаю о создании ссылок, но доступ к элементу за пределами массива - неопределенное поведение.Так что да, ваш код полагается на неопределенное поведение.

1 голос
/ 01 октября 2011
char& ref = array[6];

Это нормально, если размер array минимален 7. В противном случае это неопределенное поведение (UB).

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

Это нормально, если array[6] инициализирован или ему присвоено какое-то значение. В противном случае это UB.

0 голосов
/ 01 октября 2011

Нет, это не неопределенное поведение.Это похоже на определение указателя.Ссылка - это указатель с более дружественным и менее подверженным ошибкам синтаксисом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...