вопрос по приведению типов и const, собственно, сабж:
#include <iostream>
int main()
{
const int a = 333;
const int * ap = &a;
int * p = (int*) ap; // <-оно
*p = 444;
std::cout << "*p ="<< *p << "\n" <<"*ap=" << a << "\n"
<< " p = "<< p << "\n" << "ap = " << ap << "\n";
}
output:
*p =444
*ap=333
p = 0x72fdad7ee70c
ap = 0x72fdad7ee70c
вопросы:
1. приведение const в не-const таким способом это UB? (где бы почитать в смысле директ линка на стандарт если это оно?)
2. как по одному адресу могут находиться два — разных — значения?
Здравствуйте, brainy, Вы писали:
B>1. приведение const в не-const таким способом это UB?
Да.
Снимать константность и модифицировать объект можно только если объект изначально не был константным. То есть, например, такой код допустим и определён:
int a = 333;
const int * ap = &a;
int * p = (int*) ap;
*p = 444;
B>(где бы почитать в смысле директ линка на стандарт если это оно?)
В стандарте и смотри. В разделе
[dcl.type.cv]. Там и твой пример есть.
B>2. как по одному адресу могут находиться два — разных — значения?
Наблюдаемый вывод — не следствие того, что в одной ячейке памяти находятся два разных значения, а следствие того, что поведение программы не определено.
(В реальности тут компилятор даже не смотрит что лежит в памяти по указателю. Он знает, что там было число 333, и он знает, что константы менять нельзя. Поэтому делает вывод, что по указателю
ap может быть только число 333, и, собственно, выводит число 333).
Здравствуйте, brainy, Вы писали:
B>1. приведение const в не-const таким способом это UB? (где бы почитать в смысле директ линка на стандарт если это оно?)
https://en.cppreference.com/w/cpp/language/const_cast
Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.
const int j = 3; // j is declared const
int* pj = const_cast<int*>(&j);
// *pj = 4; // undefined behavior
Здравствуйте, brainy, Вы писали:
B>вопрос по приведению типов и const, собственно, сабж:
B>
B>B>#include <iostream>
B>int main()
B>{
B> const int a = 333;
B> const int * ap = &a;
B> int * p = (int*) ap; // <-оно
B> *p = 444;
B> std::cout << "*p ="<< *p << "\n" <<"*ap=" << a << "\n"
B> << " p = "<< p << "\n" << "ap = " << ap << "\n";
B>}
B>
B>output:
B>*p =444
B>*ap=333
B> p = 0x72fdad7ee70c
B>ap = 0x72fdad7ee70c
B>вопросы:
B>1. приведение const в не-const таким способом это UB? (где бы почитать в смысле директ линка на стандарт если это оно?)
B>2. как по одному адресу могут находиться два — разных — значения?
Ответ на второй вопрос -- у вас опечатка в коде:
"*ap=" << a << "\n"
После исправления все становится нормально без всякого UB.
Здравствуйте, uentity, Вы писали:
U>Ответ на второй вопрос -- у вас опечатка в коде: "*ap=" << a << "\n"
U>После исправления все становится нормально без всякого UB.
Ну нет, не становится. Undefined behavior остаётся.
Здравствуйте, brainy, Вы писали:
B>вопросы:
B>1. приведение const в не-const таким способом это UB? (где бы почитать в смысле директ линка на стандарт если это оно?)
B>2. как по одному адресу могут находиться два — разных — значения?
1) Поиск по сайту рулит
2) Не ссылка на стандарт, впрочем она очевидна, но таки объяснение темы, которое нравится лично мне
http://rsdn.org/forum/cpp/2644701Автор: Erop
Дата: 04.09.07
3) А что ты хотел сделать на самом деле? Речь об ошибке в программе, которая неожиданно для тебя проявилась, или о какой-то идее хака, которая недовзлетела?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском