Это неопределенное поведение, чтобы отбросить константу параметра функции? - PullRequest
15 голосов
/ 31 января 2012

Представьте, что у меня есть эта функция C (и соответствующий прототип в заголовочном файле)

void clearstring(const char *data) {
    char *dst = (char *)data;
    *dst = 0;
}

Есть ли неопределенное поведение в приведенном выше коде, отбрасывает const прочь ,или это просто ужасно плохая практика программирования?

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

char name[] = "pmg";
clearstring(name);

Ответы [ 2 ]

24 голосов
/ 31 января 2012

Попытка записи в *dst - это UB , если , вызывающая сторона передает вам указатель на const-объект или указатель на строковый литерал.

Но если вызывающая сторона передаетЕсли вы указатель на данные, которые на самом деле являются изменчивыми, то поведение определяется.Создание const char*, которое указывает на модифицируемое char, не делает его char неизменным.

Итак:

char c;
clearstring(&c);    // OK, sets c to 0
char *p = malloc(100);
if (p) {
    clearstring(p); // OK, p now points to an empty string
    free(p);
}
const char d = 0;
clearstring(&d);    // UB
clearstring("foo"); // UB

То есть ваша функция крайне опрометчивапотому что вызывающему так легко вызвать UB.Но на самом деле его можно использовать с определенным поведением.

0 голосов
/ 24 апреля 2015

Рассмотрим функцию, подобную strstr, которая, если получить указатель на часть объекта, содержащего строку, возвращает указатель на возможно отличную часть того же объекта. Если в метод передается указатель на область памяти, доступную только для чтения, он вернет указатель на область памяти, доступную только для чтения; аналогично, если ему дается указатель на область для записи, он возвращает указатель на область для записи.

В C нет способа заставить функцию возвращать const char *, если ей дано const char *, и возвращать обычную char *, когда ей дано обычное char *. Чтобы быть совместимым с тем, как strstr работал до того, как к языку была добавлена ​​идея const char *, он должен преобразовать константный указатель в неконстантный указатель. Хотя верно и то, что библиотечная функция strstr может иметь право выполнять такое приведение, даже если пользовательский код не может этого сделать, такой же шаблон встречается достаточно часто в пользовательском коде, поэтому было бы целесообразно запретить его.

...