Const_cast позволяет изменить константу на путь, ведущий к константе ?

Учитывая этот код (из моего последнего сообщения здесь):

  const int j = 5; // constant object
  const int *p = &j; // `p` is a const access path to `j`

  int *q = const_cast<int *>(p); // `q` is a non-const access path to `j`
  *q = 10;

  cout << *q << endl;

Вывод: 10

Предполагается, что это так? Я думал, что этот код должен был привести к неопределенному поведению, поскольку j является константой. Я ошибся ?

Спасибо


person JAN    schedule 14.07.2012    source источник
comment
Итак, ваш реальный вопрос: разрешено ли программе с неопределенным поведением выводить 10\n на консоль? и ответ Да.   -  person Ben Voigt    schedule 14.07.2012
comment
Вы думали, что это привело к неопределенному поведению. Так и было. В чем проблема?   -  person Konrad Rudolph    schedule 14.07.2012
comment
Even though const_cast may remove constness from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const invokes undefined behavior. Так что это неопределенное поведение. Источник   -  person Olwaro    schedule 14.07.2012
comment
@Olwaro: Прекрасно, я не буду использовать его в будущем.   -  person JAN    schedule 14.07.2012
comment
Этот почти идентичный const_casting вопрос спрашивает, почему вывод не изменился.   -  person Bo Persson    schedule 14.07.2012


Ответы (3)


Неопределенное поведение может быть чем угодно — оно может делать именно то, что вы хотите, или оно может разрушить вселенную. Если возможно, избегайте неопределенного поведения, поскольку я действительно не хочу, чтобы меня уничтожали только потому, что вы слишком ленивы, чтобы делать что-то правильно.

person Christian Stieber    schedule 14.07.2012

http://en.wikipedia.org/wiki/Undefined_behavior

Это, в частности, освобождает компилятор от выполнения самых простых и эффективных действий, если такая программа будет отправлена. В общем, любое поведение после этого также не определено. В частности, никогда не требуется, чтобы компилятор диагностировал неопределенное поведение — поэтому может показаться, что программы, вызывающие неопределенное поведение, компилируются и даже работают без ошибок поначалу, а затем завершаются сбоем в другой системе или даже в другую дату. Когда происходит неопределенное поведение, с точки зрения спецификации языка может произойти что угодно, а может и вообще ничего.

person Caesar    schedule 14.07.2012

Оптимизатору не нужно много усилий, чтобы понять, что

*q = 10;
std::cout << *q;
// not use q anymore

Можно переписать как

std::cout << 10;

А q можно убрать, потому что сейчас он не используется.

После этого p и j также больше не используются и могут быть удалены.

Все это при условии, что вы не ввели в свою программу какое-либо неопределенное поведение. Допущение, которое может сделать компилятор.

person Bo Persson    schedule 14.07.2012