const — по-разному ли обрабатываются идентификаторы в C ++?

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

#include <iostream>

int main()
{
const int integer = 2;
void* tmp = (void*)&integer;
int* pointer = (int*)tmp;

(*pointer)++;

std::cout << *pointer << std::endl;
std::cout << integer << std::endl;

return 0;
}

вывод этого кода:

3
2

Итак, я путаю то, что я изменил на земле? что значит integer стоять за?

-2

Решение

Изменение consts не определено. Компилятор может хранить бесплатно const Значения в частях памяти, доступных только для чтения, выдают ошибку при попытке их изменения (бесплатно, не обязательно).
Неопределенное поведение плохо, нежелательно и его следует избегать. Таким образом, не делайте этого.

PS integer а также pointer имена переменных в вашем коде, но не особо хорошие имена.

4

Другие решения

Вы использовали небезопасные приведения в стиле C, чтобы отбросить постоянство. C ++ не является безопасным языком, поэтому вы можете делать такие безумные вещи, как этот. Это не значит, что вы должны. Фактически, вы вообще не должны использовать приведение в стиле C в C ++ — вместо этого используйте reinterpret_cast, const_cast, static_cast и dynamic_cast. Если вы сделаете это, вы обнаружите, что способ изменить значения const — это использовать const_cast, который в точности соответствует языку.

3

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

Когда вы заявляете integer как константа, и использовать ее в выражении, оптимизации компилятора и заменить ее константным литералом, который вы ей присвоили.
Но фактическое содержание ячейки памяти, указанной &integer изменено Компилятор просто игнорирует этот факт, потому что вы определили его как константу.

Увидеть Const Correctness в C ++. Обратите внимание на вывод ассемблера чуть выше раздела «Оператор Const_cast» на этой странице.

0

Вы въезжаете на территорию неопределенного поведения.

Если ты пишешь

void* tmp = &integer;

компилятор выдаст вам ошибку. Если вы написали хороший код C ++ и написали

void* tmp = static_cast<void*>(&integer);

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

Есть несколько способов, которыми компилятор мог бы справиться с этим, не в последнюю очередь из которых:

  1. Это может занять адрес местоположения в сегменте кода, где значение, например, загружается в регистр.
  2. Это может занять адрес местоположения аналогичный значение.
  3. Он может создать временное значение, поместив значение в стек, взяв адрес местоположения, а затем вытолкнув стек.

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

Рассматривать

    const char h = 'h';
const char* hello = "hello";
const unsigned char num = 2 * 50 + 2 * 2; // 104 == 'h'
arg -= num; // sub 104, eax

char* ptr = (char*)(&h);

Компилятор может выбрать сохранение «h» специально для целей «ptr», или он может сделать так, чтобы «ptr» указывал на «h» в привет. Или он может выбрать расположение значения 104 в инструкции ‘sub 104, eax’.

0

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

-1
По вопросам рекламы [email protected]