Преобразование const_cast в ссылку lvalue не удаляет константу

Я хотел бы понять разницу ниже двух случаев.

const uint32_t v0 = 0;
const uint32_t v1 = 1;

const_cast<uint32_t&>(v0) = v1;
std::cout << v0 << std::endl;

Этот результат:

0

Тем не мение,

struct S {
    const uint32_t v0;
    S() : v0( 0U ) {}
} s;

const_cast<uint32_t&>(s.v0) = v1;
std::cout << s.v0 << std::endl;

Я получил:

1

Что касается первого случая, почему "v0" остается 0?

Заранее спасибо.

1 ответ

Решение

Применение const_cast на данных, а затем их изменение, которое на самом деле является константой, имеет неопределенное поведение. Причина в том, что константные данные могут быть помещены компилятором в постоянную память. Таким образом, попытка изменить его приведет к UB, какой вывод будет зависеть от компилятора.

Также, как указал @Yakk, компилятор может фактически использовать только значение постоянной переменной, чтобы уменьшить использование памяти. В этом случае любое выражение, в которое вовлечена постоянная переменная, редактируется для замены переменной на фактическое значение, поэтому в памяти ничего нет. И если вы попытаетесь изменить содержимое памяти, будьте готовы к BOOM.

Итог: не делай этого.

Другие вопросы по тегам