LINUX.ORG.RU

Re: strlen и другие извращения C

а зачем?

bugmaker ★★★★☆ ()

Re: strlen и другие извращения C

Если охота всяких удобств, используй Ц++ и STL, а что-нть простенькое, просто на Ц (ибо Ц++, как известно, не трУЪъ и реальные пацаны это не юзают) можно написать и самому.

Deleted ()

Re: strlen и другие извращения C

ну вот зачем городить ненужные сущности скажи мне ?

зачем это надо ? и кому это надо ?

alphex_kaanoken ★★★ ()
Ответ на: Re: strlen и другие извращения C от alphex_kaanoken

Re: strlen и другие извращения C

:)) Прости но меня это очень уж улыбнуло. Как ты представляешь себе что делает strlen() сейчас? Она ищет длину строки таким вот способом:

while (c != '\0') {
c = str[i];
i++;
}

И оптимизировать это никак нельзя. Скажем строку в 100 символов оно считает практически незаметно, но если делать это 5000 раз (например: массовое переименование файлов, парсинье mp3 тегов, листание директории, etc). Не проще ли:

return str.len;

Как бонус если правильно переписать функции в strings.h и string.h то buffer overflow станеть гораздо более редкой проблемой. Ну и все функции типа snprintf идут лесом.

Krechet ()

Re: strlen и другие извращения C

А зачем это в libc-то пихать?

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

Teak ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

> Как бонус если правильно переписать функции в strings.h и string.h то buffer overflow станеть гораздо более редкой проблемой. Ну и все функции типа snprintf идут лесом.

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

Просто пользуйся другим языком. Тебя ж никто не заставляет писать именно на C, правда?

Teak ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

> И оптимизировать это никак нельзя.

Почему?

> Скажем строку в 100 символов оно считает практически незаметно, но если делать это 5000 раз (например: массовое переименование файлов, парсинье mp3 тегов, листание директории, etc).

Так делайте правильно, в чем проблема?

Sorcerer ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Teak

Re: strlen и другие извращения C

А как же overloading? Пару версий glibc будут две версии каждой функции. Потом старое метится как depricated, потом obsolete. Процес уже давно отработан.

А про скорость - смотри мой пост выше. То как сделанно сейчас медленнее даже при ПУСТОЙ! строке чем если со структурой. Так что невижу пока аргументов кроме "а лень".

Krechet ()
Ответ на: Re: strlen и другие извращения C от Sorcerer

Re: strlen и другие извращения C

>Так делайте правильно, в чем проблема?

В том что надо делать повсеместно и сразу (e.g. POSIX).

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

так

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

alphex_kaanoken ★★★ ()

Re: strlen и другие извращения C

> Может и боян но... Так почему же никто так и не сделал нечто типа:

> в glibc? В чем загвоздка?

Потому что ты гонишь. ASCIIZ строки самодостаточны - а ты предлагаешь для строки сделать два разобщенных объекта - собственно, ту же самую ASCIIZ строку, и структуру непонятного назначения.

Используй C++/STL, как тебе уже указали - и не изобретай велосипед, оно того не стоит.

Spectr ★★★ ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Ты вообще в курсе что кроме Linux/glibc есть и другие платформы? И ты в курсе, сколько софта написано на C, который ради твоей прихоти никто переписывать не собирается?

Тебе зачем это именно в glibc-то пихать, расскажи?

Teak ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

> Как почему? Потому что нельзя: ты что предлогаешь

Я предлагаю предоставить такой алгоритм, который будет невозможно написать без многократного использования strlen и других "извращений" C. Это и будет являться доказательством утверждения, что "оптимизировать это никак нельзя".

Sorcerer ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Spectr

Re: strlen и другие извращения C

Тогда зачем интересно есть такие классы как int, long int, double, etc? Ведь они по сути 4 byte'а или там 8. 1 байт ведь самодостаточен.

В любом случае по моему ни у кого нет желания переписывать такие вещи как Linux kernel на С++. А прибавка скорость при копировании многих мелких файлов и листании директорий будет реальная. И как насчет баз данных?

Ну и еще: что ты думаешь есть String class в C++? Правильно! Объект "непонятного назначения" поверх ASCII строки.

И то что я предложил - не мой велосипед.

ЗЫ а можно ссылку/имя такой библиотеки?

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

> Тогда зачем интересно есть такие классы как int, long int, double, etc?

Хм... Ты явно что-то не то курил... Завязывай с такой травой.

> Ну и еще: что ты думаешь есть String class в C++? Правильно! Объект "непонятного назначения" поверх ASCII строки.

Вполне понятного, и притом, очень качественно написанный (по крайней мере, в нормальных либах - у GCC с этим все ок).

Spectr ★★★ ()
Ответ на: Re: strlen и другие извращения C от Spectr

Re: strlen и другие извращения C

Ну а я о чем? Я же и говорю что если в С++ есть такой класс то приведенная выше структура имеет право на жизнь.

Krechet ()
Ответ на: Re: strlen и другие извращения C от Teak

Re: strlen и другие извращения C

>Я что-то не понял, а почему мне не отвечают? :)

Извени незаметил.

>Ты вообще в курсе что кроме Linux/glibc есть и другие платформы?

В курсе. И что?

>И ты в курсе, сколько софта написано на C, который ради твоей прихоти никто переписывать не собирается?

Так переписывать особо ничего не недо. Вплоть до того что можно сделать header file и прописать туда хитрый макрос. А прибавка в производительности получается бесплатная.

>Тебе зачем это именно в glibc-то пихать, расскажи?

Затем чтоб в итоге все делали этим способом и не чурались strlen. Чтоб в С все работало искаропки. Ну и чтоб когда это вкльючат в glibc все посмотрят с скажут: Кашерна!

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Хех, ну так попробуй напиши хитрый макрос, всунь его в string.h, а потом пересобери всю систему с ним Ж) (будет новый дистриб: SuperGentoo)
А где обратная совместимость, где?

Deleted ()

Re: strlen и другие извращения C

USE pascal

И вообще, может в этой строчке, завершенной 0 полгое собрание сочинений Ленина хранится, а ты хочешь урезать его до int.

anonymous ()
Ответ на: Re: strlen и другие извращения C от anonymous

Re: strlen и другие извращения C

Pascal замечательный язык но С мне нравится больше. Ну а то что пересобирать систему так не волнуйтесь - за вас это сделает Патрик. А гентушники сами все все равно пересобирают при каждом апдейте glibc. Так что нет возражений/аргументов?

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

>Так что нет возражений/аргументов?

А это тебе чем не возражение/аргумент?:

>И вообще, может в этой строчке, завершенной 0 полгое собрание сочинений Ленина хранится, а ты хочешь урезать его до int.

Ramen ★★★★ ()
Ответ на: Re: strlen и другие извращения C от anonymous

Re: strlen и другие извращения C

>И вообще, может в этой строчке, завершенной 0 полгое собрание сочинений Ленина хранится, а ты хочешь урезать его до int.

А какого типа вообще указатели сами по себе, что они позволяют работать с традиционными строками, содержащими полное собрание сочинений Ленина? А как устроена работа с большими файлами (>4Gb)?

Допустим вот реализуют в glibc такую вещь, кто ее будет использовать? Будут все равно в основном использовать стандартные кроссплатформенные char* функции. И что-то мне кажется, что никакими хитрыми макросами тут подменить одно другим нельзя.

Deleted ()
Ответ на: Re: strlen и другие извращения C от anonymous

Re: strlen и другие извращения C

Ну а как вот до всех остальных символов добраться, если уж int'а якобы не хватает?? Так что это не аргумент, а глупость полная.
Тем более, если вспомнить о том, что на реальных системах макс. размер виртуальной памяти доступной процессу ограничен (4гб или 2 на 32-битных?), так что сколь угодно длинной строки все равно быть не может.

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

Чем 
struct string_new_standart {
   int len;
   char* str;
}

менее кросс платформенно char* str? А про макрос так все просто:

#define strlen     strlen_new_standart
#define printf     printf_new_standart
...
#define char*      string_new_standart*

усё? Можно правда не извращятса и написать шелловый скрипт 
который заменит все char* на string_new_standart*. 
Потом ставится новый glibc, Патрик тратит пару ночей на 
пересборку гент^Wслаки и всем наступает счастье.

Krechet ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

long long'а за глаза хватит. Или двух. А вообще по моему строка >4GB это гораздо менее кошерно чем то что сейчас творится в strings.h.

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Ага, а потом берем старый рабочий кусок кода.

char* str;
str = malloc(1024*sizeof(char));
fgets(str,1023,stdin);
printf("first character is: %c", str[0]);

и смотрим в какую кашу он превращается после таких макросов.

Т.е переопределять еще и придется способ доступа к такой строке, ибо str[0] уже не канает. Ц это не умеет, зато умеет Ц++ и... так это же получается stl!

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

Подожди. А как насчет сделать:

string_new_standart* create_string() {

string_new_standart* sns = malloc(sizeof(string_new_standart));
   sns.len = 0;
   sns.str = malloc(sizeof(char));

   return sns;
}

Таким образом твой код превращяется в:

string_new_standart sns = create_string();
fgets_new_standart(sns, stdin);   

//длинну строки указывать больше не надо так как 
//fgets_new_standart сам все определит и динамически 
//увеличит выделенную память

printf("first character is: %c", sns.str[0]); 

доступ к str[0] теперь просто по sns.str[0] или по некой функции типа:

char get_char_in_string_new_standart(string_new_standart* sns, int i) {

   if (i >= sns.len) {
      error("out of bound error\n");
      return '\0';
   }
   else return sns.str[i];

}

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Как видишь такой подход очистит код, уберет головную боль о выделении памяти если fgets ждет 1023 символа, а получает 1024, ускорит некоторые процессы и уменьшит количество функцый в почти 2 раза. А про совместимость ныть не надо: API/ABI в glibc меняется с каждым релизом. Я еще раз утверждаю: тут нет ничего с чем не справился бы простой скриптик.

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Используй C++ и не делай с мозгами собеседников то, к чему предназначены совершенно другие органы.

Xellos ★★★★★ ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Вот! Подменить одно другим не удастся, можно лишь добавить новое к уже существующему и переписывать свой код при желании заюзать новые строки.
Но:
1) ради экономии на strlen, пошли усложнения других функций, что съест возможный прирост производительности.
2)ну и наконец это велосипед :) google -> fast string library -> одна из первых ссылок http://bstring.sourceforge.net/bstrFAQ.shtml

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

Про библиотеки шас почитаю, но смысл вего этого не только в strlen но и в fgets, snprintf и т.д. Динамические строки это хорошо потому что не надо себе ипать моск всякими мыслями типа "а вдруг имя файла диннее чем 1023 char'а?".

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

:) я рад :)
просто стандартные строки - самая простая библиотека, дающая самый полный контроль над тем что творится внутри, а у динамических строк есть своя фига в кармане...

пример, обычные строки:

char data[1024];
fgets(data, 512, stdin);
char* tmp 0;
tmp = find_first_appearence_of_symbol('a',data);
strcat(data, " something", 511);
if(tmp!=0)printf("print begin from 'a': %s",tmp);

тут все ок

а теперь:

newstr* data = create_newstr(); //динамическая память тормознее
newfgets(data,stdin);
char* tmp = find_first_appearence_of_symbol('a',data->str);
newstr* tmp2 = new_find_first_appearence_of_symbol('a',data); //копирование всей подстроки? или просто новый указатель на середину имеющегося буфера? а если модифицировать будем? нужен copy-on-write механизм - в любом случае overhead.
newstrcat(data,"something");
if(tmp!=0)printf("print begin from 'a': %s",tmp);
//Бухаха! Возможен segfault, ибо data могло реаллокнуться во время newstrcat


Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

в догонку:
if(tmp2!=0)new_printf("print begin from 'a': %s",tmp2);
результат совсем неочевиден и сильно зависит от деталей реализации.
упрощаем в одном - усложняем в другом.

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

В первом примере та же проблема что и во втором:


tmp = find_first_appearence_of_symbol('a',data); 

Потом если ты модифицируешь tmp:

tmp[0] = 'b';

то data меняется тоже. И тот же copy-on-write нужен.


Во втором примере:

newstr* data = create_newstr(); //динамическая память тормознее

в данном случае разници в скорости практически не будет. Там один malloc а там два. Оба очень мелкие.


char* tmp = find_first_appearence_of_symbol('a',data->str); //это не надо следующая строка все сделает

newstr* tmp2 = new_find_first_appearence_of_symbol('a',data); //фактически tmp2->str = index(str, 'a') но если будем менять tmp2 
//то тогда часть data копируется в другое место в памяти и tmp2->str меняется

Для такого можно устроить например 

struct newstr {
   int len;
   char* str;
   int refcount; //количество структур ссылающихся на часть или весь str
   //меняется это значение по вызову new_index и иже с ними
}



Вместо

if(tmp!=0)printf("print begin from 'a': %s",tmp); 

делаем

if(tmp2->str!=0)new_printf("print begin from 'a': %s",tmp2); 

и получается что

strcat(data, " something", 511);
if(tmp!=0)printf("print begin from 'a': %s",tmp); 

и

newstrcat(data,"something");
if(tmp2->str!=0)new_printf("print begin from 'a': %s",tmp2);

одно и то же. Суть ведь не меняется потому что что то что то все равно в итоге обращается к tmp2->str что является char*.

Krechet ()
Ответ на: Re: strlen и другие извращения C от Krechet

Re: strlen и другие извращения C

Что-то путанно ты написал, я так и не понял...
Вот придумал более наглядный пример.

Классика:
char data[1024] = "abcd";
char* tmp = index(data,'c');
strncat (data,"ef",10);
strcat (tmp,"gh",10);
printf(data); //выведет abcdefgh

New:
newstr* data = create("abcd");
newstr* tmp = find(data,'c');
newstrcat(data,"ef");
newstrcat(tmp,"gh");
printf(data);

подумаем как оно должно быть реализовано, чтобы получилось abcdefgh?
считая, в худшем случае, что при каждом newstrcat происходил realloc newstr->str?

Копировать весь str после во время find заранее не имеет смысла, ибо printf(data) уже точно не напечатает то что нам нужно.

Если реализован copy-on-write, то после find имеем tmp->str=*(data-
>str[2]), первый же realloc сменит data->str, а прежде занятую им память надо сохранять, дабы не сломать tmp->str, а потом все-таки освободить, причем включая первые две буковки, о которых tmp ничего не знает... Это первая проблема.
А во-вторых и в этом случае printf не напечатает то что нужно.

Усложняем структуру :)

struct newstr{
int len;
char* str; //указатель на начало нашей строки внутри strbuff->buff
smartchar* strbuff; //смарт-пойнтер для непосредственно строковых данных
}

struct smartchar{
int refcount;
char* buff; //данные, для них делается malloc и realloc
}

newstr* find(newstr* data, char ch){
newstr* ret = malloc(sizeof(newstr));
ret->strbuff = data->strbuff;
ret->strbuff->refcount++;
ret->str = index(data->strbuff->buff,ch);
return ret;
}

void newstrcat(newstr* dest, char* src){ //char* src для упрощения
char * tmp = malloc(dest->len+strlen(len));
strcat(tmp,dest->strbuff->buff);
strcat(tmp,src);
dest->strbuff->refcount--;
free(dest->strbuff->buff);
if(dest->strbuff->refcount == 0){
free(dest->strbuff);
}
dest->strbuff = malloc(sizeof(smartchar));
dest->strbuff->buff = tmp;
}


Весело получается?
Работает старая формула:
удобство*дуракоустойчивость*производительность = e^pi

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

s/char * tmp = malloc(dest->len+strlen(len));/char * tmp = malloc(dest->len+strlen(src));/


И еще, не уверен, но когда используем
char str[1024]
никакого malloc не вызывается, память выделяется статически, а это гораздо быстрее.

Deleted ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

Ну во-первых

char data[1024] = "abcd";
char* tmp = index(data,'c');
strncat (data,"ef",10);
strcat (tmp,"gh",10);
printf(data); //выведет abcdefgh

это как раз и есть пример того чего делать не стоит (см. выше о плохих алгоритмах). Просто потому что так можно не значит что это хороший способ. Ни в одном другом широко распостроненном языке (включая C++) ты так не сделаешь потому что там строка это строка, а не область памяти. И я думаю не ничего что останавливает С наконец вылезти из каменного века в этом вопросе.

>Весело получается?

Получается не плохо. Могло бы быть и хуже. Учти что от програмиста все это будет спрятанно - он видит только удобство подхода где не не надо забивать себе на каждом шагу голову вопросами о том что будет со строкой которая не помещается в n бит. А написать этот код надо всего один раз (или взять из одной из библиотек по ссылке которую ты привел выше).

>Работает старая формула:
>удобство*дуракоустойчивость*производительность = e^pi

Удобство возрастает - благодоря более простой системе теперь не надо задумыватся о всей этой фигне с malloc-ами когда работаешь со вторым самым популярным типом данных. Не надо морочить себе мозги вопросами типа "а какая максимальная длина имени файла?" (приведи кастати элегантное решение этой проблемы используя char*).

Дуракоустойчивость возрастает - нет больше понятия buffer overflow со строками.

Производительность возрастает за счет функции strlen и всех функций которые ее используют: strcat, printf, etc.

Короче значение pi меняется. Ж)

Krechet ()
Ответ на: Re: strlen и другие извращения C от Deleted

Re: strlen и другие извращения C

>И еще, не уверен, но когда используем >char str[1024] >никакого malloc не вызывается, память выделяется статически, а это гораздо быстрее.

Может быть но не в char* str = malloc(1024*sizeof(char));

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