Мой пример использования следующий:
Я разрабатываю библиотеку, в которой некоторые загруженные плагины могут создавать объекты (выделяемые библиотекой с помощью malloc()
), а некоторые другие плагины могут читать свойства этих объектов, ноне изменяйте их.
Для меня это случай использования не-1006 * API для стороны создания / записи и const
API для стороны читателя, например:
// writer API
struct obj *obj_create(void);
void obj_set_some_property(struct obj *obj, int property);
// reader API
int obj_get_some_property(const struct obj *obj);
Библиотека преобразует struct obj *
(созданный на стороне писателя) в const struct obj *
(доступный на стороне читателя).
Моя проблема в том, что эти объекты также имеют счетчики ссылок, ичитатель может вызывать ваши типичные функции увеличения / уменьшения счетчика ссылок.Эти функции должны модифицировать объект.
Мой вопрос: в этом конкретном контексте безопасно ли для функций увеличения / уменьшения счетчика ссылок принимать const struct obj *
и отбрасывать const
внутренне?Обратите внимание, что функция уменьшения количества ссылок может также уничтожить (освободить) объект, если счет достигнет нуля.
Я знаю, что §6.7.3¶5 говорит:
Если попыткасделано для изменения объекта, определенного с помощью const-квалифицированного типа, с помощью lvalue с не-const-квалифицированным типом, поведение не определено .
Я просто могу 't выяснить, что означает , определенный с помощью константного типа .Применимо ли это, если мой объект выделен в куче?Я полностью понимаю, почему было бы UB сделать это с указателем литеральной строки (.rodata
), например.Но что, если объект создан, чтобы быть не const
в начале?
strchr()
- это хорошо известный пример отбрасывания const
: он принимает const char *
и возвращает char *
, что указывает на параметр const char *
.Как это законно, учитывая §6.7.3¶5?