Найти число в массиве

Что делает неправильное поведение недопустимого объекта (ссылка, указатель, что угодно) неопределенным: lvalue-to-rvalue conversion (§4.1):

Если объект, к которому относится ссылка glvalue не является объектом типа T и не является объектом типа, производного от T, или если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение.

Предполагая, что мы 't перегружен operator&, унарный оператор & принимает lvalue в качестве своего операнда, поэтому никакого преобразования не происходит. Наличие только идентификатора, как и в x;, также не требует преобразования. Вы получите только неопределенное поведение, когда ссылка используется как операнд в выражении, ожидающем, что этот операнд будет значением rvalue, что имеет место для большинства операторов. Дело в том, что выполнение &x фактически не требует доступа к значению x.

Я считаю, что ваш код хорошо определен.

Когда перегрузка operator& была перегружена, выражение &x преобразуется в вызов функции и не подчиняется правилам встроенных операторов - вместо этого он следует правилам вызова функции. Для функции &x вызов функции перевода означает либо x.operator&(), либо operator&(x). В первом случае преобразование lvalue-rvalue будет происходить на x, когда используется оператор доступа к члену класса. Во втором случае аргумент operator& будет инициализирован с помощью x (как в T arg = x), а поведение этого зависит от типа аргумента. Например, в случае, если аргумент является ссылкой lvalue, нет неопределенного поведения, поскольку преобразование lvalue-rvalue не происходит.

Итак, если operator& перегружен для типа x, код может быть или не быть корректным, в зависимости от вызова функции operator&.

Можно утверждать, что унарный оператор & полагается на наличие хотя бы некоторой допустимой области что у вас есть адрес:

В противном случае, если тип выражения равен T, результат имеет тип «указатель на T» и является значением praleue, которое является адрес выделенного объекта

И объект определяется как область хранения. После уничтожения объекта, эта область хранения больше не существует.

Я предпочитаю полагать, что это приведет только к неопределенному поведению, если к нему действительно обращается недопустимый объект. Ссылка все еще полагает, что это относится к некоторому объекту, и он может с радостью указать адрес, даже если он не существует. Однако это, кажется, некорректная часть стандарта.


Кроме

В качестве примера неопределенного поведения рассмотрим x + x. Теперь мы попали в другую нечеткую часть стандарта. Категория значений операндов + не указана. Как правило, из § 5/8 вытекает, что если он не указан, тогда он ожидает значение prvalue:

Всякий раз, когда выражение glvalue появляется как операнд оператора, который ожидает prvalue для этого операнда , для преобразования выражения в prvalue применяются переменные lvalue-to-rvalue (4.1), стандартные переменные (4.2) или стандартные функции (4.3).

Теперь, поскольку x является lvalue, требуется преобразование lvalue-rvalue, и мы получаем неопределенное поведение. Это имеет смысл, потому что добавление требует доступа к значению x, чтобы он мог выработать результат.

13
задан muskox 23 December 2016 в 17:01
поделиться