LINUX.ORG.RU

Нелогичность в stdlib

 


0

2

Почему функции

char *strpbrk(const char *s, const char *accept);
char *strstr(const char *haystack, const char *needle);
char *strcasestr(const char *haystack, const char *needle); // GNU
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
Возвращают char вместо const char? Может я упускаю какой-то сакральный смысл? Просто преобразование `return (char *)s;`, нарушает все допустимые нормы программирования (MISRA, NASA JPL, etc). Да и просто по логике - взяли константную строку на вход, на выходе позволяем делать с ней все, что угодно.

★★★★★

Ответ на: комментарий от PPP328

Перечисленные тобой «стандарты качества кода» нужны далеко не везде. Более того, они предназначены не для «удобства программиста», а для уменьшения количества ошибок в результирующем коде. Поэтому кому-то придется оборачивать тело strstr в макрос и делать два варианта функции, а кто-то просто повторит интерфейс libc-шной и будет доволен.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Поэтому кому-то придется оборачивать тело strstr в макрос и делать два варианта функции, а кто-то просто повторит интерфейс libc-шной и будет доволен.

Ни то ни другое не позволит обойтись без (char *)const char *

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Ни то ни другое не позволит обойтись без (char *)const char *

#define STRSTR_IMPL(char_t, haystack, needle) \
  char_t *result; \
  ... \
  return result

const char *strstr_const(const char *haystack, const char *needle) { STRSTR_IMPL(const char, haystack, needle); }
char *strstr(char *haystack, const char *needle) { STRSTR_IMPL(char, haystack, needle); }
kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Тогда нарушается соглашение о const-входящего параметра. Компилятор не сможет без него нормально заоптимизировать. Я ж говорю, АПИ спроектировано глупо.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Во-первых, покажи, в каком месте у меня нарушилось соглашение о const.

Во-вторых, компилятор не полагается на const — это сахарок для человека. С точки зрения алиасинга const char* и char* — одинаковые типы. Наглядная демонстрация: https://godbolt.org/g/h248nf (если убрать restrict, загрузка из const char* указателя будет происходить на каждой итерации цикла).

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

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Во-первых, покажи, в каком месте у меня нарушилось соглашение о const.

Я имею в виду нарушение в обратную сторону - не изменяете строку, но нет const.

Во-вторых, компилятор не полагается на const — это сахарок для человека

4.2

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

https://s7.postimg.org/45guz2sqj/2017-11-30_13-41-09.png

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Я имею в виду нарушение в обратную сторону - не изменяете строку, но нет const.

Твои предложения, когда нужно

char *c = strchr(str, 'a');
if (c)
  *c = 'b';
?

4.2

И тут ты врываешься с контр примером.

https://s7.postimg.org/45guz2sqj/2017-11-30_13-41-09.png

Каждый раз, когда топящий за высокие стандарты кодирования не вписывает return во все бранчи функции, я начинаю думать, что этими высокими стандартами он исключительно троллит на форуме. Чем ты вообще компилируешь-то, что такой код на выходе?

https://s2.postimg.org/6cpfs6jzt/image.png

kawaii_neko ★★★★
()
Последнее исправление: kawaii_neko (всего исправлений: 1)
Ответ на: комментарий от PPP328

i32

В наш век смотрится не очень, и я вполне могу себе представить ситуацию, когда символ будет найден как раз в самом конце 4-гигабайтного блока данных. ssize_t.

Я рад, что мне не нужно следовать некоторым убогим правилам, поэтому останусь с любимым паттерном TYPE* search(const TYPE*, ...).

kawaii_neko ★★★★
()
Ответ на: комментарий от PPP328

Г-пади, да что вы прицепились к этому ssize_t? Вы для чего типик создали, чтобы показать своё упрямство? Или типа с одними не прокатило, так с другими попробуем?

Представьте, что ваш if(pos >= 0) в глубоко вложенной функции от текущей. Удобно? Да ОТВРАТИТЕЛЬНО!

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вам все равно надо проверять на NULL. ВСЕГДА. И в чем разница? с ssize_t даже errno становится не нужен - можно передать тип ошибки через -1, -2, -3...

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Вам все равно надо проверять на NULL. ВСЕГДА.

Да блин, опять 25. Ясен пень. Но на NULL мы проверяем str, а вам надо в каждую функцию тянуть этот pos. Который нафиг не нужен, ибо нам надо str+pos везде, а не foo(str+pos, pos).

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.