[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
N.B: Котировочные переменные являются хорошей практикой.
blockquote>
const_cast
не убирает постоянство переменной, как определено. Если бы вы передавали неконстантную переменную по ссылке в метод, использующий константную ссылку, такую как void foo(const int& x)
, то вы могли бы использовать const_cast
для изменения значения x
в пределах foo
, но только если переменная фактически переданный не был const во-первых.
Код в приведенном примере транслируется в следующий ассемблер:
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.
Мораль истории в том, что константы времени компиляции должны оставаться постоянными, потому что именно это вы и говорите компилятору. Мораль истории в том, что отбрасывание констант для изменения константы может привести к плохим вещам.
.Вы не должны изменять значение const. Есть причина, по которой оно константируется и попытка изменить его, скорее всего, приведет только к ошибкам. Если const хранится в секции памяти только для чтения, то вы получите нарушения доступа.
.Это один из случаев, когда константное приведение не определено, так как код, вероятно, был оптимизирован таким образом, что w на самом деле не является переменной и на самом деле не существует в скомпилированном коде.
Попробуйте следующее:
const volatile int w = 10;
int &wr = const_cast <int &> (w);
wr = 20;
std::cout << w << std::endl;
Во всяком случае, я бы не советовал злоупотреблять const_cast таким образом.
Почему ты не можешь просто перевязать константу? Поэтому вместо
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;
). Необязательные присваивания будут оптимизированы компилятором - потому что мы видели, что он выполнил такую оптимизацию, так как именно по этой причине был задан вопрос.
Здесь есть освежитель, следует отметить, что это на 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! */
Полагаю, что объявление w const позволяет компилятору выполнять более агрессивные оптимизации, такие как вставка значения w и переупорядочивание инструкций. Каким образом w, по-видимому, изменится или нет, зависит от того, какие оптимизации были применены в конкретном случае и не под вашим контролем.
Вы не можете заставить w быть полностью констеблем. Конс_каст должен быть намеком программисту на то, что он может делать что-то подозрительное.