Вопрос

$ 5.2.11 / 7 - «[Примечание: в зависимости от типа объекта, операция записи через указатель, lvalue или указатель на элемент данных, возникающих в результате Const_cast, который отказывается от complifier68) мая производить неопределенное поведение (7.1.5.1). ] "

Функции этого раздела (C ++ 03) удивительны для меня. Чем чувствует, что две вещи.

а) Во-первых, использование «может». Почему это «может»? Другие места в стандарте очень окончательно о неопределенном поведении

б) почему то, что отбрасывание конденсности первоначально объекта Const не сразу «неопределенное поведение». Почему требуется запись для запуска UB?

Это было полезно?

Решение

а) Во-первых, использование «может». Почему это «может»? Другие места в стандарте очень окончательно о неопределенном поведении

Не выглядеть слишком глубоко в использовании слова мая здесь. Дело в том, что отбрасывание постоянной связи в этом случае вызывает неопределенное поведение.

Стандарт C ++ использует «May» или «может» часто, как в:

1.3.12: неопределенное поведение мая Также ожидается, когда этот международный стандарт пропускает описание любого явного определения поведения.

Упор мой. По сути, стандарт использует слово «может» как в «разрешено".

б) почему то, что отбрасывание конденсности первоначально объекта Const не сразу «неопределенное поведение». Почему требуется запись для запуска UB?

Пишите триггеры UB, потому что возможно, что объекты Const могут храниться в памяти только для чтения на определенных платформах.

Другие советы

Мое понимание заключается в том, что он будет только UB, если рассматриваемый объект принципиально является объектом Const, а не указатель Const или ссылка на объект, который не был изначально Const.

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

Бывший:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.

Для комментариев ниже, потому что код выглядит ужасно в комментариях:

В §7.1. 5.1 / 4 стандарта, приведенный пример:

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object

Так что это специально разрешено.

Для вашего первого вопроса, если что-то мая производить неопределенное поведение, то это не делает его менее неопределенным.

Для второй части я представлял, что это для совместимости. Например, C не (или не, до C99) иметь const Ключевое слово, поэтому, если вы хотите пройти объект const к функции C, постоянная связь должна быть выброшена. Таким образом, стандарт C ++ указывает, что это допускается до тех пор, пока нет записи. Если функция C является только для чтения, постоянная связь может быть безопасно выброшена.

Даже в C ++, непоследовательный или неполный конденс-корректность тоже довольно распространен. Таким образом, мы иногда бегаем в ситуации, когда мы должны отбрасывать Const-Ness, чтобы пройти объект Const к функции, которая не модифицирует свой аргумент, но принимает его не-Const.

Я бы поверил, что это потому, что const Объект может храниться в памяти только для чтения. Таким образом, написание на него может иметь много различных эффектов: сбой программы, неисправность сегментации или отсутствие эффекта.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top