Сравнение pchar и array of char

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
Nik
энтузиаст
Сообщения: 573
Зарегистрирован: 03.02.2006 23:08:09
Откуда: Киров
Контактная информация:

Сравнение pchar и array of char

Сообщение Nik »

Вопрос к знатокам по просьбе коллег с форума wincmd.ru. Оригинальное обсуждение здесь.

Действительно ли не работает сравнение p>buffer в таком вот коде (в Delphi пример работает):

Код: Выделить всё

var p:pchar; 
       buffer:array[0..259] of char;
 begin
   strcopy(buffer,"this is a test");
   p:=strend(buffer);
   while (p>=buffer) do begin
      // do something, e.g. if p[0]=' ' then p[0]:=#9;
      dec(p);
   end;
 end;


Имеет ли смысл постить эту багу (?) в трекер?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Действительно не работает.
Правильнее, конечно, писать не "p>=buffer", а "p>=@buffer[0]" (и тогда оно работает), но попытки FPC преобразовать обе стороны выражения в строки и сравнивать их - ни в какие ворота не лезут.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

pchar - указатель, который может быть неявно преобразован в строку
array of char - массив char, который тоже может быть неявно преобразован в строка (неявных переход от array [] of char к строке был придуман именно в delphi, в TP такое нельзя было делать).
как итог - выражение само по себе скорее сравнение строк, а не работа с указателями!
или в FPC есть приоритет выборки "неявных" типов? =)

теперь я понимаю, почему TC вызывает подсознательное отторжение и я пользуюсь FAR-ом :mrgreen:
кстати, Gishler пишет "I have many 100s of these constructs in my code, so I can't simply convert them all.", то скорее всего такая проблема возникнет, только с неявными строками. А другие места заработают правильно. и потом, раз уж он по $100 за плагин платит! мог бы финансы на коррекцию кода направить :mrgreen: ... хотя легко чужие деньги считать :mrgreen:

имхо, правильный код такой:

Код: Выделить всё

var i:integer; 
       buffer:array[0..259] of char;
 begin
   strcopy(buffer,'this is a test');
   i:=0;
   while (i<length(buffer)) and (buffer[i]<>#0) do begin
      // do something, e.g. if buffer[i]=' ' then buffer[i]:=#9;
      inc(i);
   end;
 end;


2 Nik,  отпишись пожалуйста про sellexecute
daesher
постоялец
Сообщения: 221
Зарегистрирован: 09.03.2010 21:17:14

Сообщение daesher »

Nik писал(а):   while (p>=buffer) do begin

А чего Вы хотите от бедного компилятора? Даже с точки зрения чистой логики (а Паскаль - именно логичный язык), Вы пытаетесь сравнить указатель с массивом. Указатели можно сравнивать с указателями, массивы - вообще неизвестно, как сравнивать, разве что поэлементно (то, что в Delphi массив автоматически превращается в указатель, не совсем логично). И тут такая "лазейка": и то, и другое можно превратить в строку!
Ответить