LINUX.ORG.RU
Ответ на: комментарий от Unknown

> побайтовое копирование, которое не эффективно - всегда быстрее копировать блок памяти

Покажи бенчмарки? На разных длинах строк, ага.

kemm
()
Ответ на: комментарий от Unknown

> до свиданья, ваш "высокий" уровень не позволяет нам общаться на равных

Т.е. вы не только не способны понять то, с чем начали спорить, но даже не можете дочитать параграф до конца? Как печально...

kemm
()
Ответ на: комментарий от Unknown

> просто не хочу общаться в таком тоне

Извини.

Только тогда сам прекращай писать про криворуких и прочий бред, ага?

>> Я писал про то, что str(n)cat использовать может только камикадзе. В тех случаях, когда применимо использование этих функций, ВСЕГДА лучше вместо них использовать strlcat.

Ну или g_strlcat, по ситуации. Аналогично про str(n)cpy, который ещё кривее str(n)cat. В ряде случаев ещё лучше будет использовать функцию с семантикой, аналогичной strl-функциям из солярки (биздишный вариант копирует не вылезая за размер буфера с завершающим нулём, соляркин -- если суммарный размер строк больше буфера, не меняет содержимое dst).

Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.

Есть какие-нибудь возражения против этого?

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

>Строки могут появляться из генератора псевдослучайных последовательностей aka "пользователь".

Они ограничены размером буфера, про который всё известно заранее.

>ввести строку заново или использовать обрезанный вариант

Кошмар ) Надеюсь, вы несерьёзно.

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

> Только тогда сам прекращай писать про криворуких и прочий бред

да я вроде и не делал таких заявлений, может вы меня спутали с другим, но хорошо - буду следить за собой

> Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.


точно также можно сказать, что snprintf не лезет ни в какие ворота, так уж вышло - и приходится просто помнить этот ньюанс, т.к., как я уже писал, лучшего варианта в libc нет( почему лично мне strlcat не нравится - я уже упоминал )

Unknown
()
Ответ на: комментарий от Davidov

> Они ограничены размером буфера, про который всё известно заранее.

А ввод пользователя ещё экранировать надо. Ну бывают иногда ситуации, когда размер данных неизвестен.

> Кошмар ) Надеюсь, вы несерьёзно.

Случаи бывают разные. В тех случаях, где применимы strn?(cat|cpy) -- применимы и strl(cat|cpy), причём использование последних предпочтительнее. Они применимы не всегда, но сделаны они прямо, в отличие от. Замучался уже повторять, ей-богу.

kemm
()
Ответ на: комментарий от Unknown

> точно также можно сказать, что snprintf не лезет ни в какие ворота

Не-не-не. У snprintf/strlcat/strlcpy и прочего семантика логичнее -- мы передаём размер, больше которого получить не должны ни в каком случае. strncat и Дреперовский вариант -- передаём размер, на один меньше размера буфера. Нелогично. (Про strncpy я вообще молчу -- оно просто не гарантирует завершение нулём)

> лучшего варианта в libc нет

Ну так в libc много чего нет... А что есть -- порой через задницу сделано как минимум в одном варианте из более-менее распространённых.

> почему лично мне strlcat не нравится - я уже упоминал

Тем, что в любом случае изменяет dst, или я перепутал? Ну так возьми соляркин -- он работает в предложенном тобой стиле. Для записи в лог вполне подходит биздишный вариант, для более ответственной работы лично я бы всё равно предпочёл работать без фиксированных буферов, пожалуй.

У strl(cat|cpy) правильная идея -- они соответствуют по параметрам другим стандартным функциям, они предоставляют возможность проверить на переполнение, они гарантируют корректное завершение строки. Это именно то, как должны были бы выглядеть strn-функции.

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

>У strl(cat|cpy) правильная идея .... они гарантируют корректное завершение строки.

siz = 0 и твои правильные ф-ции дружно обсираются ибо уже не гарантируют завершение результирующей строки NULL.

imhotep
()
Ответ на: комментарий от kemm

>У strl(cat|cpy) правильная идея ... они предоставляют возможность проверить на переполнение

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

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

> siz = 0 и твои правильные ф-ции дружно обсираются ибо уже не гарантируют завершение результирующей строки NULL.

Адрес скажи, куда санитаров вызывать... 8))

kemm
()
Ответ на: комментарий от imhotep

> возвращая длину результирующего ввода которая будет вычиляться _всегда_ даже если приемный буфер всего пара байт а на ввод поступило пара килобайт - формируй такие длинные вводные строки искуственно и вот тебе готовое решение для отказа в обслуживании.

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

Впрочем, ладно. Специально тебе я разрешаю использовать strcat и strncat, только с одним условием -- каждый раз, когда использование этого приведёт к проблемам, ты будешь съедать по свежекупленной шляпе.

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

Санитары тут причем ? По существу есть что сказать ? Или ты не согласен что если оказалось по какой-то причине siz == 0 и результирующий буфер был не NULL terminated то твое утверждение неверно ? Мысль Дреппера была прямой и понятной - strl ф-ции не решат проблем а завуалируют создав новые.

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

> Или ты не согласен что если оказалось по какой-то причине siz == 0

По какой причине? Что значит -- "оказалось"?!

> и результирующий буфер был не NULL terminated то твое утверждение неверно ?

Если бы у бабушки были усы...

Бред сивой кобылы. Попросил записать не больше 0 байт -- тебе столько и записали. Если бы ты сказал записать 0 байт -- а тебе записали 1 байт, то именно это и есть фигня, баг и проблема, а не наоборот.

Дрепер несёт чушь, не моргнув глазом, ты за ним повторяешь. strl-функции не создают ни одной проблемы сверх str(n), причём пачку их проблем, наоборот, решают.

Учись не слепо следовать за авторитетами, а иногда думать своей головой. Ошибаются все. И Дрепер, и Торвальдс, и Кокс, и Тео де Раат, и Дилан, и МакКузик, и... Кого там из признанных гуру позабыл?

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

>По какой причине? Что значит -- "оказалось"?!

В твоих поделках все буферы статические заранее известной длины и ты всегда можешь передать ее константой sizeof ?

>Дрепер несёт чушь


чушь несешь ты, на котрую я больше реагировать не намерен.

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

> В твоих поделках все буферы статические заранее известной длины

o_O А в твоих -- нет?! Статический буфер неизвестной длины?!

> и ты всегда можешь передать ее константой sizeof ?

o_O А ты не можешь?!

> чушь несешь ты, на котрую я больше реагировать не намерен.

У-тю-тю. Ты хоть своими словами-то способен озвучить хоть одну проблему strlcat, которой нет у strncat? Обратную ситуацию в рамках этого треда я озвучил уже раз 10.

Не можешь? Записываешься в почётные golodranez'ы и отправляешься строевым шагом служить Родине единственным доступным способом. 8))

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

>Статический буфер неизвестной длины?!

Дебил - вспомни о существовании динамической памяти. Видимо не дано тебе понимать нормальную речь.

>хоть одну проблему strlcat, которой нет у strncat?


Дебил - читай то что было написано ранее в этом треде.

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

> вспомни о существовании динамической памяти.

Статический буфер в динамической памяти? О, сколько нам открытий чудных...

> Видимо не дано тебе понимать нормальную речь.

Ты сам себя-то хоть понимаешь? 8)))

> читай то что было написано ранее в этом треде.

Т.е. нет ни одной такой проблемы у strlcat, которой не было бы у strncat? Так я это и так знаю, и талдычу для альтернативно одарённых уже в пятнадцатый раз. В обратную сторону неверно, опять-таки в пятнадцатый раз повторяю. И ещё в пятнадцатый раз: из этого следует, что нет ни одного оправдания использованию strncat при наличии strlcat в обозримой OSS-вселенной. Использование strcat частенько оправдано, но не уровне компетентности автора поста (и некоторых комментаторов, ога).

PS: да, можешь не подписываться перед каждой своей фразой, я тебя и так узнаю.

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

>Статический буфер в динамической памяти?

можешь продолжать паясничать и коверкать фразы - умней ты от этого даже не кажешься, наоборот - неумело хочешь скрыть отсутствие элементарных знаний

>нет ни одной такой проблемы у strlcat, которой не было бы у strncat

>знаю, и талдычу


талдычишь и даже не пытаешься читать то что пишут другие, а проблем как минимум 3 уже озвучено

>PS: да, можешь не подписываться перед каждой своей фразой


дебил - это не подпись а ты, но если настаиваешь, я больше не буду писать про это, ты и так теперь знаешь это :)

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

> можешь продолжать паясничать и коверкать фразы

Я говорил про статический буфер или всё-таки ты? Я потом вдруг резко начал говорить пр динамическую память или всё-таки ты? Ну и кто тут паясничает?

> умней ты от этого даже не кажешься, наоборот - неумело хочешь скрыть отсутствие элементарных знаний

У-тю-тю, даже сам себя ты понять не в состоянии, а ещё чего-то пыжишься... 8))))

> талдычишь и даже не пытаешься читать то что пишут другие, а проблем как минимум 3 уже озвучено

Ну так ты озвучь эти три проблемы в одном месте своими словами, топливо. Третий комментарий пытаюсь от тебя добиться этой газификации, всё бестолку, даже газификация у тебя выходит какая-то беспредметная. 8))

PS: ну я же просил -- не надо подписываться, там одну подпись движок сайта вставляет, её достаточно.

kemm
()
Ответ на: комментарий от true_admin

> Какашками ещё покидайтесь.

по-моему данный процесс уже в самом разгаре

Unknown
()
Ответ на: комментарий от kemm

>Причём в качестве альтернативы предлагает использовать нестандартную функцию (mempcpy),

а почему это она стала нестандартной? C89 и C99 уже не стандарты? (man по крайней мере о таких говорит)

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

memcpy -- стандарт, mem_p_cpy, которую предлагает использовать Дрепер -- 'This function is a GNU extension.'

Впрочем, основная проблема там всё-таки в необходимости странно передавать размер буфера, а именно на 1 меньше действительного. По крайней мере, я не вижу ни одной причины использовать такой вариант. Это число (размер буфера - 1) имеет какой-то странный физический смысл. Это ни размер буфера, ни максимальное кол-во для записанных байт...

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

> Впрочем, основная проблема там всё-таки в необходимости странно передавать размер буфера, а именно на 1 меньше действительного. По крайней мере, я не вижу ни одной причины использовать такой вариант. Это число (размер буфера - 1) имеет какой-то странный физический смысл. Это ни размер буфера, ни максимальное кол-во для записанных байт...

Это длинна строки без учёта '\0'. По идее, эту функцию удобно применять при конкатенации строк.

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

> Это длинна строки без учёта '\0'.

Это понятно, но использовать именно это значение -- нелогично и противоречит, например, snprintf/strftime. Строки в C не бывают без завершающего нуля. По определению.

> По идее, эту функцию удобно применять при конкатенации строк.

Какую именно? Чем удобно?

kemm
()
Ответ на: комментарий от Deleted

Наверно предполагалось, что размер буфера будет всегда вычисляться как strlen(".."). 8)))

irishka
()
Ответ на: комментарий от kemm

> Какую именно?

memcpy

> Чем удобно?


DESCRIPTION
The mempcpy() function is nearly identical to the memcpy(3) function. It copies n bytes from the object beginning at src into the object pointed to by
dest. But instead of returning the value of dest it returns a pointer to the byte following the last written byte.

This function is useful in situations where a number of objects shall be copied to consecutive memory positions.

А У. Дреппер - весьма своеобразная личность, есть такое =).

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

> memcpy

В смысле, mempcpy? Ну, в принципе, да. Но лучше делать в виде функции с семантикой strl-функций. Явно необходима сигнализация "обрезания", а то фигня выходит. И использовать размер буфера удобнее.

> А У. Дреппер - весьма своеобразная личность, есть такое =).

А они все такие. 8)) Что Линус, что Тео, что Мэт...

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

>memcpy -- стандарт, mem_p_cpy, которую предлагает использовать Дрепер

да, не разглядел буквы p

chicane
()
Ответ на: комментарий от kemm

>Один хрен, использовать strn?(cat|cpy) -- диверсия. Дальше каждый выкручивается как хочет, strl-функции -- просто одно из готовых рабочих проверенных решений.

А слабо

strncat (s1, s2, BUFSIZE-1);
s1[BUFSIZE-1] = 0;

?

Или BSD отучает мыслить, но предоставляет "готовые проверенные решения"?

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

> Или BSD отучает мыслить, но предоставляет "готовые проверенные решения"?

писать везде по две строки вместо одной( если уж хочется такое поведение strcat ) - тоже не дело, лучше написать ту самую функцию

П.С. обрезание результата - дефективное by design (c)

Unknown
()
Ответ на: комментарий от linuxfan

> Или BSD отучает мыслить, но предоставляет "готовые проверенные решения"?

Это линукс, судя по всему, отучает мыслить, а предлагает выдумывать кривые велосипеды с треугольными колёсами. 8))

kemm
()
Ответ на: комментарий от linuxfan

> strncat (s1, s2, BUFSIZE-1);

Кстати, за использование здесь констант можно и канделябром схлопотать в абсолютном большинстве случаев. sizeof для кого придумывали?

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

>Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.

Я тут немного man почитал. n — это количество символов от конца строки dst до конца буфера в dst. Так что семантика очень даже правильная и полностью соответствует семантике snprintf'а, который, кстати, тоже не будет писать завершающий нулевой байт, если размеров буфера не хватит.

linuxfan
()
Ответ на: комментарий от kemm

>Кстати, за использование здесь констант

Кстати, за незнание аргументов strncat можно было бы и со стыда покраснеть ;)

       A simple implementation of strncat() might be:

           char*
           strncat(char *dest, const char *src, size_t n)
           {
               size_t dest_len = strlen(dest);
               size_t i;

               for (i = 0 ; i < n && src[i] != '\0' ; i++)
                   dest[dest_len + i] = src[i];
               dest[dest_len + i] = '\0';

               return dest;
           }

linuxfan
()
Ответ на: комментарий от Unknown

> а для кого тогда придумали malloc? :)

malloc придумывали для других ситуаций, когда усечение результата неприменимо. Уймись уже, бывают места, где не столь важно, урезана ли строка или нет. 8))

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

> Уймись уже, бывают места, где не столь важно, урезана ли строка или нет. 8))

не спорю, но мы то в общем вроде рассматриваем, или нет?

Unknown
()
Ответ на: комментарий от linuxfan

> Я тут немного man почитал. n — это количество символов от конца строки dst до конца буфера в dst.

Правильно. И?

> Так что семантика очень даже правильная и полностью соответствует семантике snprintf'а

Нет. Не правильная и не соответствует.

> который, кстати, тоже не будет писать завершающий нулевой байт, если размеров буфера не хватит.

Что, простите? Вы где _это_ вычитали? Выкиньте.

Кстати, strncat, в отличие от strncpy, завершает строку нулём. Точнее, за строкой. 8)) Оно пишет ноль n + 1ым байтом.

kemm
()
Ответ на: комментарий от Unknown

> не спорю, но мы то в общем вроде рассматриваем, или нет?

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

kemm
()
Ответ на: комментарий от linuxfan

> Кстати, за незнание аргументов strncat можно было бы и со стыда покраснеть ;)

Ну красней, я не против... 8))

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

> в любом месте, где применимы strn-функции, лучше их не использовать, нет?

для любого места - strl заменяет один баг( segmentation fault ) на другой( ошибка в логике работы программы ), как по мне второе ничем не лучше и даже опаснее, так как труднее отлавливается и может привести к порче данных

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

> вы размер буфера через strlen хотите получить?

Не, для strncat strlen необходим. Правильный вариант строки 'strncat(s1, s2, sizeof(s1) - strlen(s1) - 1)'

kemm
()
Ответ на: комментарий от Unknown

> для любого места - strl заменяет один баг( segmentation fault )

Нет там sigsegv'а. Там некорректное завершение строки, которое ловится ничуть не проще, чем обрезание.

> на другой( ошибка в логике работы программы )

(тяжко вздыхая) Выходим на сто первый круг. Нет ошибки в логике программы, там допустимо обрезание строки или там есть проверка переполнения. Точка. strl-функции позволяют корректно сделать как и допустимое обрезание, так и проверку, не обрезан ли результат.

> как по мне второе ничем не лучше и даже опаснее, так как труднее отлавливается и может привести к порче данных

Если там действительно косяк, и использовать str(n|l) никак нельзя -- то в случае strn последствия хуже. И обнаруживаются не проще, ага. Хрен редьки не слаще, но strl чуть-чуть вкуснее.

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