изменение значения переменной константы в C++ [дубликат]

[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

N.B: Котировочные переменные являются хорошей практикой.

16
задан Paul Stephenson 5 January 2010 в 13:23
поделиться

7 ответов

const_cast не убирает постоянство переменной, как определено. Если бы вы передавали неконстантную переменную по ссылке в метод, использующий константную ссылку, такую ​​как void foo(const int& x), то вы могли бы использовать const_cast для изменения значения x в пределах foo, но только если переменная фактически переданный не был const во-первых.

5
ответ дан 30 November 2019 в 17:04
поделиться

Код в приведенном примере транслируется в следующий ассемблер:

    movl    $10, 28(%esp)  //const int i = 10; 
    leal    28(%esp), %eax //int* wp = const_cast <int*>(&i);
    movl    %eax, 24(%esp) //store the pointer on the stack
    movl    24(%esp), %eax //place the value of wp in eax
    movl    $20, (%eax) //*wp  = 20; -  so all good until here
    movl    $10, 4(%esp) //place constant value 10 onto the the stack for use in printf
    movl    $.LC0, (%esp) // load string
    call    printf //call printf

Так как исходный int i был объявлен константой, компилятор оставляет за собой право использовать литеральное значение вместо значения, хранящегося в стеке. Это значит, что значение не меняется и вы застряли с исходными 10.

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

.
8
ответ дан 30 November 2019 в 17:04
поделиться

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

.
2
ответ дан 30 November 2019 в 17:04
поделиться

Это один из случаев, когда константное приведение не определено, так как код, вероятно, был оптимизирован таким образом, что w на самом деле не является переменной и на самом деле не существует в скомпилированном коде.

Попробуйте следующее:

const volatile int w = 10; 
int &wr = const_cast <int &> (w); 
wr = 20; 
std::cout << w << std::endl;

Во всяком случае, я бы не советовал злоупотреблять const_cast таким образом.

15
ответ дан 30 November 2019 в 17:04
поделиться

Почему ты не можешь просто перевязать константу? Поэтому вместо

const int w = 10;
int* wp = const_cast <int*> (&w);
*wp = 20;
// some code

просто введите другую константу с тем же именем

const int w = 10;
{
   const int w = 20;
   // the same code
}

Если "новая" константа должна зависеть от ее собственного значения, то следует ввести другую константу (const int _w = w; const int w = _w * 2;). Необязательные присваивания будут оптимизированы компилятором - потому что мы видели, что он выполнил такую оптимизацию, так как именно по этой причине был задан вопрос.

2
ответ дан 30 November 2019 в 17:04
поделиться

Здесь есть освежитель, следует отметить, что это на C. Это обманчиво хитроумное обоснование использования переменной или указателя с помощью ключевого слова const. Это подчёркивает разницу между указателем переменной foo и тем, как его значение может измениться при использовании указанного ключевого слова.

char const *foo;

char * const foo;

const char *foo;

Первое и последнее объявления делают данные , на которые указывает 'foo' только для чтения , но вы можете изменить адрес, на который указывает 'foo', например,

const *char foo; /* OR char const *foo */

char str[] = "Hello";

foo = &str[0]; /* OK! */

foo[1] = 'h'; /* BZZZZTTT! Compile Fails! */

Среднее объявление в описанном выше, делает указатель только для чтения , т.е. вы не можете изменить адрес данных, на которые указывает 'foo'

char * const foo;

char str[] = "Hello";

foo = &str[0]; /* BZZZZTTT! Compile Fails! */
1
ответ дан 30 November 2019 в 17:04
поделиться

Полагаю, что объявление w const позволяет компилятору выполнять более агрессивные оптимизации, такие как вставка значения w и переупорядочивание инструкций. Каким образом w, по-видимому, изменится или нет, зависит от того, какие оптимизации были применены в конкретном случае и не под вашим контролем.

Вы не можете заставить w быть полностью констеблем. Конс_каст должен быть намеком программисту на то, что он может делать что-то подозрительное.

0
ответ дан 30 November 2019 в 17:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: