литерал, будучи r-значением дает нам указатель на константые данные в статической памяти. Тогда почему это компилируется?
char *str = "1234";
*str = '0';
Даже без ворнингов. Clang 12 на linux mint, никаких вербозных флагов компилятора не включал. Да, я получаю сегфолт, но все же
При этом меня сильно смутило следующее
const int a = 42;
int *b = &a;
*b = 10;
printf("a = %d, b = %d", a, *b);
Тут я получаю ворнинг и вывод 42, 10. Число было скопировано? Куда?
Или я нарвался на UB? Четкого понимания взаимодействия указателей на константы и неконстанты нет(
И то, и другое -- UB. Для диагностики и вообще чистоты кода рекомендую всегда собирать с -Wall -Wextra -Werror. Можно ещё -pedantic для гурманов.
Во втором случае скорее всего выделился кусочек стека в момент взятия адреса, но это всё не имеет значения.
Первое явно разрешено в си (каст, не запись), второе я удивлен, что компилируется
Спасибо С этими флагами первый пример все еще компилируется и все еще сегфолт во втором я получаю ошибку :)
Т.е. можно скастовать указатель на константу до указателя на неконстанту, но при попытке перезаписи по адресу будет ub?
так константа же после компиляции н чем не отоичается от неконстанты
так константа же после компиляции н чем не отоичается от неконстанты
С чего бы численная константа гарантированно не отличалась? В некоторых асмах (ЕМНИП x86 среди них) небольшие численные константы просто зашиты в параметрах операций (типа add r0, 1 -> r1). При наличии оптимизации Constant Propagation вместо выделения места на стеке под константную переменную её значение пропагируется к юзерам, что вместе с наличием механизма зашивания численных констант в аргументы операций делает понятие адреса константной переменной бессмысленным. Ну и Constant Propagation - эта одна из основных оптимизаций, так что сомневаюсь, что она отключена в -O0.
Для строк да
Обсуждают сегодня