Подтвердить что ты не робот

Как возвращение strstr не является константой

Стандартная функция strstr используется для определения местоположения подстроки в строке. Оба аргумента функции имеют тип const char *, но тип возврата char *.

Я хотел бы знать, как реализована стандартная функция, нарушающая const-правильность.

4b9b3361

Ответ 1

C позволяет указывать на память с константными или неконстантными указателями, независимо от того, был ли объект определен с помощью определителя константы или нет.

6.5 Выражения

  1. Объект должен иметь сохраненное значение, доступ к которому имеет только выражение lvalue, которое имеет один из следующие типы:

- квалифицированная версия типа, совместимая с эффективным типом объекта,

Прототипом strstr в C является:

char *strstr(const char *s1, const char *s2);

Возвращаемый указатель, если он действителен, указывает на строку s1. Это может быть достигнуто с помощью cast:

const char safe = 's' ;
char* careful = ( char* )&safe ;

Проблема заключается в изменении этой памяти.

6.7.3 Типовые классификаторы

  1. Если предпринимается попытка изменить объект, определенный с использованием типа const, используя lvalue с неконстантно-квалифицированным типом, поведение undefined.

Поскольку вы создали строку, вы должны знать, можете ли вы ее изменить или нет, поэтому вы можете принять возвращаемое значение с указателем на const, чтобы избежать каких-либо проблем:

const char* find = strstr( ... ) ;

Ответ 2

Все const char * сообщают вам, что strstr не собирается изменять строку, которую вы передаете в нее.

Если вы измените возвращаемую строку или нет, это зависит от вас, так как это ваша строка!

В С++ это было изменено перегрузкой метода и наличием двух версий, входная версия const имеет выход const.

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

Ответ 3

В соответствии с ISO С++ 21.8 (7) strstr возвращает a const char* или char* в зависимости от того, получает ли он const char* или char*.

const char* strstr(const char* s1, const char* s2);

char* strstr( char* s1, const char* s2);

Ответ 4

Это делается путем указания подписи и оставления реализации до компиляторов.

Обратите внимание, что возвращение a char*, указывающее на строку const char[], просто опасно, но еще не является нарушением какого-либо правила. Однако любая попытка записать в эту память по-прежнему Undefined Поведение.

Ответ 5

Функция strstr восходит к эпохе, прежде чем появилась такая вещь, как указатель const. В случаях было бы законным для того, чтобы код записывал в память, идентифицированный первым указателем, переданным в strstr, было бы законным для того, чтобы код записывал в память, идентифицированную возвращенным указателем, и в тех случаях, когда возвращаемое значение было бы используется в путях, которые были законными с указателем на постоянную память (например, строковый литерал), можно было законным образом передать такой указатель на strstr.

Если сегодня была определена функциональность, аналогичная strstr, она может быть реализована с использованием двух методов: один из которых может принимать любой указатель и возвращать указатель, который не может быть написан получателем, и один из них только принимать записываемые указатели, но возвращать указатель, который получатель мог бы использовать по своему усмотрению. Потому что для некоторого кода, который использовал strstr, нужно было бы использовать указатели только для чтения, а потому, что для некоторого кода, который использовал strstr, нужно было писать указатели, которые он мог бы дать при задании записываемых указателей, имеют один набор квалификаций указателя в обоих направлениях. Следствием этого является набор квалификаций указателей, которые на самом деле не являются "безопасными" [поскольку он может возвращать записываемый указатель на область памяти только для чтения), и это позволит компиляции кода в некоторых случаях, когда это действительно "не должно", но который позволит коду, написанному до дней указателей const, продолжить работу по назначению.

Ответ 6

С++ содержит две версии, которые принимают аргументы const и те, которые принимают неконстантные.

const char* strstr( const char* str, const char* target );      
char* strstr(       char* str, const char* target );

Так как в C мы не можем перегружать, мы оставляем два неприятных варианта:

  • Либо мы принимаем аргументы как неконстантные, но если наши источники действительно являются константами, нам нужно выполнить неприятный перенос в неконстантный.
  • Второй вариант - это тот, который мы имеем, что мы принимаем аргументы как const, но возвращаем не const. Мы могли бы вернуть const char *, но тогда мы не смогли бы изменить результат.

Ответ 7

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