Re[45]: Об эффективности программ
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.05 13:35
Оценка: 6 (2) +1
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хотел было прекоатить — так не получается.

PD>Твое ? Тогда смотри дальше.
Да.
PD>Где здесь дают эту самую длину ? Ответь, пожалуйста.
Я показывал. Павел, я уже начинаю уставать. Я попросил тебя дать примеры того, откуда берутся строки без длины. Ты привел пример с едитом — неправда, он отдает длину. Ты утверждал, что даже если бы длина была, все равно ее пришлось бы вычислять — неправда, есть невычисляющие конструкторы. Теперь мы наконец переходим к той части аргументации, которая не является банально неверной.

PD>Где длина строки в текстовом файле ? Где она там хранится ? Там нет и нуля, конечно — по известным тебе историческим причинам. Но ограничитель там есть. (0D0A).

Ну и что? Как это нам помешает получить длину? Достаточно сделать вот так:
long initialPosition;
long finalPosition;
initialPosition = ftell(stream);
char line[4000];
fgets(line, 4000, stream);
finalPosition = ftell(stream);
int len = finalPosition - initialPosition;

Вуаля! У нас есть длина строки от fgets без вычисления.
PD>Где она после того, как fgets вернула строку?
В указателе файла, с которым работала fgets.
PD>Если мы будем делить источники на основные и неосновные, то спор уйдет в никуда.PD> Ты приводишь случаи, когда ее дают. Я — когда нет. Для того, чтобы ты был прав — необходимо, чтобы давали всегда. В противном случае твое утверждение необоснованно. Теорема, для которй есть хоть один опровергающий пример, опровергнута.
Павел, именно этим и отличается академический подход к разработке программ от прикладного. С прикладной точки зрения совершенно несущественно существование источников, которые передают информацию с потерями. Важнее — возможность воспользоваться нормальными источниками. Напомню, что ты пока не дал ни одного примера источника, который бы не позволил получить информацию о длине строки, кроме консоли.

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

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


PD>Нет. Они нужны для передачи этих строк в качестве входных аргументов этих самых винапи функций.

Да-да. Я и говорю — см. выделение.
PD>Я, кстати, об этом написал, но ты предпочел на эту часть моего письма не ответить, а просто выкинуть ее. Можешь все же ответить?Формулирую прямо

PD>Если в винапи используются строки с длиной, почему почти ни одной функции винапи эта длина не передается ? Почему они принимают только char* (wchar*) и вычисляют эту длину у себя внутри сами ?

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

PD>И как следствие из этого — еще один вопрос


PD>Почему, если они так делают и это правильно — когда я это делаю, это неправильно ?

Из неверной посылки следует все что угодно. Они так делают и это неправильно.
PD>Их выход — мой вход, мой выход — их вход.

S>>Действительно, в ВинАПИ есть функции, которые не позволяют получить длину строки без доп. затрат (как правило, в таких случаях можно получить точную верхнюю границу длины строки — а это позволяет нам все еще писать безопасные, хотя и не столь эффективные, алгоритмы).


PD>Хм, а ведь в том примере, с которого весь сыр-бор разгорелся (с sprintf) я же битый час доказывал, что у меня есть эта самая точная верхняя граница.

Это какая? У тебя не было никакой верхней границы. У тебя была наивная вера в существование верхней границы. А когда я говорю про точную верную границу, я говорю вот про что:

Допустим, мы воспользовались функцией fgets:

void main( void )
{
   FILE *stream;
   char line[100]; // ВНИМАНИЕ! У нас буфер размером в 100 символов

   if( (stream = fopen( "fgets.c", "r" )) != NULL )
   {
      if( fgets( line, 100, stream ) == NULL) // какое совпадение - здесь тоже n = 100
         printf( "fgets error\n" );
      else
         printf( "%s", line); // и это означает, что здесь line не длиннее 100! 
            // добавим строчку в пример MSDN:
            char line2[30];
            fgets(line2, 30, stream);
            char line3[40];
            fgets(line3, 40, stream);
      fclose( stream );
   }
}

Итак, здесь мы имеем точную верхнюю границу для суммы всех длин: она равна, очевидно, 168. Мы можем спокойно использовать для конкатенации буфер этого размера. Не потому, что где-то в БД (внешней по отношению к нашей программе!) есть размер поля, и не потому, что оператор поклялся не засыпать на пробеле, а потому, что выполняются некоторые инварианты. Функция fgets так удачно написана.

PD>Но это вызвало твою негативную реакцию. Получается, коль винапи функции могут эту границу дать или ты как-то иначе оценить можешь — им доверять можно, а если я их даю — так нельзя ? Почему ?

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

PD>Охотно допускаю, что он не менее эффективен. Но какое это к делу имеет отношение ? И винапи PathCombine можно переписать, добавив ей длины и сделав безопасной. Но этого нет. В винапи. А то, что это есть или может быть в C# — я и не спорю.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.