Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Вниз

Нашел одну вещь в Delphi   Найти похожие ветки 

 
Piter ©   (2004-11-13 17:05) [0]

Не буду говорить, что это баг - а то опять ногами запинают :)

Вообщем:

procedure TestFunc(Text: string); overload;
procedure TestFunc(Text: PChar); overload;

Угадайте с двух раз какая процедура будет выполнена:

TestFunc("test");

P.S. Проверено на D7


 
raidan ©   (2004-11-13 17:09) [1]

А как ты думаешь, какой тип по-умолчанию имеют строки типа "test"?


 
raidan ©   (2004-11-13 17:12) [2]

посмотри-ка messagedlg + F1
а потом попробуй на практике
прежде чем такое писать


 
iZEN ©   (2004-11-13 17:20) [3]

По идее должна быть выполнена первая из описанных.


 
GuAV ©   (2004-11-13 17:31) [4]

Ещё интереснее:
TestFunc(string("test"));

А ещё вопрос:
какая будет вызванна в этом случае:
asm
XOR EAX, EAX
CALL TestFunc
end;

overload вообще имхо лучше по возможности не ползоваться.


 
GuAV ©   (2004-11-13 18:07) [5]

raidan ©   (13.11.04 17:12) [2]
посмотри-ка messagedlg + F1
а потом попробуй на практике

Некоторые функции перегруженны в QDialogs.pas но не в Dialogs.pas, а документация на эти общая, отсюда и недоразумение.


 
Piter ©   (2004-11-13 18:17) [6]

raidan ©   (13.11.04 17:09) [1]
А как ты думаешь, какой тип по-умолчанию имеют строки типа "test"?


они имеют тип widestring

raidan ©   (13.11.04 17:12) [2]
посмотри-ка messagedlg + F1
а потом попробуй на практике
прежде чем такое писать


а нафига мне смотреть на messagedlg? Хочешь - сам смотри.

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


 
raidan ©   (2004-11-13 18:35) [7]

Извини, конечно, опИслся я.
Имелось в виду shellexecute.

ShellExecute(self.handle,"test", nil,nil,nil,0);
все OK

var s:string;
begin
s:="test";
ShellExecute(self.handle,s, nil,nil,nil,0);
[Error]: Incopatible types: "String" and "PAnsiChar"

И?


 
raidan ©   (2004-11-13 18:50) [8]

>GuAV ©   (13.11.04 17:31) [4]
Overload работает честно.
Никакой мистики в нем нет.
Просто нужно чуть-чуть знать, как функционируют механизмы работы со строками в Делфях, на уровне прочитавшего три книжки ;)


 
GuAV ©   (2004-11-13 19:07) [9]

raidan ©   (13.11.04 18:50) [8]
Overload работает честно.

Не отрицаю. Но им лучше не пользоваться. IMHO.


 
Ihor Osov'yak ©   (2004-11-13 22:31) [10]

по сабжу -   думаю, вторая, которая (Text: PChar)

2 [6]
>>А как ты думаешь, какой тип по-умолчанию имеют строки типа "test"?

>они имеют тип widestring

Это не так.


 
Verg ©   (2004-11-13 22:51) [11]

[4] GuAV ©   (13.11.04 17:31)

а какая из этих?!

stmdb sp!, {R3, R4, R5}
bl TestFunc

Ты чего тут ассемблерами хочешь сказать? А?!

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


 
Ihor Osov'yak ©   (2004-11-13 23:20) [12]

2 [11] Verg ©   (13.11.04 22:51)

ой, а зачем такой шум?

2 [4] GuAV ©   (13.11.04 17:31)

> asm

с ходу не могу ответить..
решил следать натурный эксперимент. Оказалось, что та, которая идет по тексту первой.. Но мое имхо здесь подсказывает, что борланды бы лучше сделали, если бы такой код вообще не компилировался..   Хотя с другой сторноны, от каждого вумника защиты не сделаешь... Я это к тому, что в определенных ситуациях [11] Verg и прав.. Если бы, конечно, не так эмоционально..


 
Игорь Шевченко ©   (2004-11-13 23:33) [13]

Ihor Osov"yak ©   (13.11.04 23:20) [12]

Дело в том, что для преобразования String в PChar нужно явно указывать это преобразование, а вот для обратного преобразования - не нужно.
Поэтому объявление таких функций есть вообще-то следствие незнания работы со строками. IMHO, разумеется.


 
GuAV ©   (2004-11-14 00:16) [14]

Verg ©   (13.11.04 22:51) [11]

Возможно и стоит отбить эту порочную склонность.
Я уже отбил охоту писать asm код в приложениях, где можно обойтись pascal кодом.
Однако желание использовать окно CPU у меня вряд ли пропадёт, пока будет возможность его использовать.

Что касается overload, это IMHO тоже порочная склонность которую я отбил ещё раньше.


 
Ihor Osov'yak ©   (2004-11-14 00:24) [15]

2 Игорь Шевченко

Подумал немного... Ваше имхо пожалуй ближе к истине, чем мое имхо по отношению к борландам..


 
GuAV ©   (2004-11-14 00:27) [16]

Игорь Шевченко ©   (13.11.04 23:33) [13]
Ihor Osov"yak ©   (14.11.04 0:24) [15]

А можно повторить понятнее, что-то я ничего не понял ?


 
iZEN ©   (2004-11-14 00:28) [17]

to Игорь Шевченко ©   (13.11.04 23:33) [13].
С другой стороны, в концепции Pascal есть приоритет исполнения для позднее описанных сущностей, то есть вторая функция, перегружающая первую, должна иметь право исполниться первой. Но из-за неявного (хотя и двусмысленного) преобразования типов строк имеем вот такую заморочку.

Заметьте: Вирт выступает против двусмысленности изначально.


 
Игорь Шевченко ©   (2004-11-14 00:39) [18]

GuAV ©   (14.11.04 00:27) [16]

Для того, чтобы передать в функцию, воспринимающую параметр PChar значение типа String, нужно указывать PChar(StringValue).
Для того, чтобы передать в функцию, воспринимающую параметр String значение типа PChar не нужно указывать String(PCharValue) - это преобразование выполнится компилятором, будет вызвана функция _LStrFromPChar, создана строка, которая и передастся в функцию.


> Что касается overload, это IMHO тоже порочная склонность
> которую я отбил ещё раньше.


Всякий овощ приносит пользу,будучи употребленным надлежащим образом в надлежащее время (с).

Я не думаю, что в Borland занимаются развитием порочных склонностей у программистов.

iZEN ©   (14.11.04 00:28) [17]


> С другой стороны, в концепции Pascal есть приоритет исполнения
> для позднее описанных сущностей


Честно говоря, не понял, нельзя ли подробнее или на примерах ?


 
GuAV ©   (2004-11-14 00:40) [19]

Игорь Шевченко ©   (13.11.04 23:33) [13]
Поэтому объявление таких функций есть вообще-то следствие незнания работы со строками. IMHO


procedure ChDir(const S: string); overload;
procedure ChDir(P: PChar); overload;

 IResponseStub = interface
 ["{4A61D005-46D3-4214-9946-5BC1DD511F02}"]
   procedure Write(varText: PChar); overload;
   procedure Write(varText: string); overload;

?


 
Игорь Шевченко ©   (2004-11-14 00:52) [20]

GuAV ©   (14.11.04 00:40) [19]

Я вообще-то написал - IMHO :)

Теперь вопрос - какая функция будет вызвана при написании
ChDir("c:\temp") ?

Кстати, реализацию этих функций тоже можно посмотреть...


 
kaZaNoVa ©   (2004-11-14 00:54) [21]

Игорь Шевченко ©   (14.11.04 0:52) [20]
вызовутся
procedure ChDir(P: PChar); overload;  
procedure Write(varText: PChar); overload;

имхо ...


 
Игорь Шевченко ©   (2004-11-14 01:05) [22]

kaZaNoVa ©   (14.11.04 00:54) [21]

Гадать здесь не нужно. Здесь нужно написать код и посмотреть в окно CPU.


 
Ihor Osov'yak ©   (2004-11-14 01:12) [23]

2 [20] Игорь Шевченко ©   (14.11.04 00:52)

> Теперь вопрос - какая функция будет вызвана при написании
я уже давал ответ на аналогичный вопрос  - в этом случае - procedure ChDir(P: PChar); overload; - так как здесь компилятор константу хранит как PChar - это более экономно, чем ansistring (предполагал, проверил на практике - действительно так);

зы - моя реплика в 12 все же была в контексте вызова процедуры из ассемблерной вставки.. в 15 мысль еще работала в том же направлении...

Хотя, если все же подумать, то примеры из [19] GuAV ©   (14.11.04 00:40)
имеют отределеное отношение к коду, который либо портирован, либо портируется на си.. - это по отношению к  ChDir..То есть, здесь как бы борьба двух не совместимых вещей - с одной стороны желание создать код, который легко портировать на си, с другой стороны - получаем то что получаем - как минимум, сложно читаемый код..

По отношению к IResponseStub - я не знаю откуда эта вещь. Если соотв. интерфейс изначально написан на си - то тогда все обьяснимо. Если изначально на делфи - то возникает много вопросов, в том числе и подозрение, озвученное в 13..


 
kaZaNoVa ©   (2004-11-14 01:12) [24]

Игорь Шевченко ©   (14.11.04 1:05) [22]

procedure TForm1.Button1Click(Sender: TObject);

procedure ChDir(const S: string); overload;
Begin caption:="1"; end ;

procedure ChDir(P: PChar); overload;
Begin caption:="2"; end;

begin
ChDir("c:\temp");
end;


результат-2

меняем местами
procedure TForm1.Button1Click(Sender: TObject);

procedure ChDir(P: PChar); overload;
Begin caption:="2"; end;

procedure ChDir(const S: string); overload;
Begin caption:="1"; end ;

begin
ChDir("c:\temp");
end;


- всё равно 2


 
GuAV ©   (2004-11-14 01:14) [25]

Игорь Шевченко ©   (14.11.04 0:39) [18]
Для того, чтобы передать в функцию, воспринимающую параметр PChar значение типа String, нужно указывать PChar(StringValue).
Для того, чтобы передать в функцию, воспринимающую параметр String значение типа PChar не нужно указывать String(PCharValue) - это преобразование выполнится компилятором, будет вызвана функция _LStrFromPChar, создана строка, которая и передастся в функцию.


И ?
IMHO это сюда не при чём. TestFunc(string("test")) всё равно вызовет PChar функцию.

Необходимость явного приведения string к pchar IMHO сделана из-за того, что PChar в отличии от string требует соблюдения, которые не проверяется на этапе компиляции, но лежат на ответсвенности программера, который делает явный typecast.

Неожиданность для некоторых результата [0] - IMHO тоже повод для отказа от overload. Я бы тоже не делал такой overload т.к. не знаю почему вызывается вторая, и не мог бы определить что вызовется вторая без проверки.

Игорь Шевченко ©   (14.11.04 0:52) [20]
Кстати, реализацию этих функций тоже можно посмотреть...


procedure ChDir(const S: string);
begin
 ChDir(PChar(S));
end;

Хе-хе. Оказывается они сделали чтобы явно не нужно было приводить строку к PChar. Всего лишь.


 
GuAV ©   (2004-11-14 01:18) [26]

GuAV ©   (14.11.04 1:14) [25]
требует соблюдения

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


 
Игорь Шевченко ©   (2004-11-14 01:20) [27]

GuAV ©   (14.11.04 01:14) [25]


> Хе-хе. Оказывается они сделали чтобы явно не нужно было
> приводить строку к PChar. Всего лишь.


Более того, я полагаю, что в реализации методов интерфейса тоже нужно следовать этому принципу.


> И ?
> IMHO это сюда не при чём. TestFunc(string("test")) всё равно
> вызовет PChar функцию.


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


> Необходимость явного приведения string к pchar IMHO сделана
> из-за того, что PChar в отличии от string требует соблюдения,
> которые не проверяется на этапе компиляции, но лежат на
> ответсвенности программера, который делает явный typecast.


Это как ? :)


 
kaZaNoVa ©   (2004-11-14 01:21) [28]

Игорь Шевченко ©   (14.11.04 1:20) [27]

> TestFunc(string("test")) всё равно
> > вызовет PChar функцию.

у меня вызывало  PChar функцию.  ...  ;)))


 
Игорь Шевченко ©   (2004-11-14 01:23) [29]

Игорь Шевченко ©   (14.11.04 01:20) [27]

Когда писал, не видел поста [26]
Да, безусловно. Можно даже еще посмотреть по коду (я просто не помню), делается ли в случае PChar(StringValue) уникальный экземпляз строки.


 
Игорь Шевченко ©   (2004-11-14 01:24) [30]

kaZaNoVa ©   (14.11.04 01:21) [28]

Ассемблер в студию можно выложить ?


 
GuAV ©   (2004-11-14 01:39) [31]

Игорь Шевченко ©   (14.11.04 1:20) [27]
Более того, я полагаю, что в реализации методов интерфейса тоже нужно следовать этому принципу.


То что overload функции должны делать одно и то же - понятно. Но вот не во всех классах реализующих IScriptProducer сделано также как и в chdir - в TScriptProducer случаи рассматриваются отдельно.

Игорь Шевченко ©   (14.11.04 1:23) [29]
делается ли в случае PChar(StringValue) уникальный экземпляз строки.


Оказывается нет.

procedure P1(P: PChar);
begin
 P^:="X";
end;

procedure TForm1.FormCreate(Sender: TObject);
var S1, S2: string;
begin
 S1:="Blah-Blah-Blah";
 S2:=S1;
 P1(PChar(S2));
 ShowMessage(S1); // Xlah-Blah-Blah
end;


 
GuAV ©   (2004-11-14 01:46) [32]

Игорь Шевченко ©   (14.11.04 1:24) [30]
А что выкладывать

ChDir(string("C:\")); компилируется как
mov eax, <адрес ASCIIZ-сторки в коде>
call <ChDir_которая_PChar>


 
kaZaNoVa ©   (2004-11-14 01:53) [33]

Игорь Шевченко ©   (14.11.04 1:24) [30]
код
procedure TForm1.Button1Click(Sender: TObject);
procedure TestFunc(Text: string); overload;
Begin caption:="1"; end;

procedure TestFunc(Text: PChar); overload;
Begin caption:="2"; end;

begin
TestFunc(string("test"));
end;


скрин CPU  webfile.ru/95466


 
GuAV ©   (2004-11-14 01:55) [34]

<off>
kaZaNoVa ©   (14.11.04 1:53) [33]
скрин CPU  webfile.ru/95466


А как сохранять CPU в текст чтоб так не извращатся ?
</off>


 
kaZaNoVa ©   (2004-11-14 01:56) [35]

GuAV ©   (14.11.04 1:55) [34]
вот я тоже не придумал без изврата ;(


 
GuAV ©   (2004-11-14 02:08) [36]

2 kaZaNoVa
@%#@%#@!
begin ... end; одной строкой не пишут, тем более в таких случаях !


 
kaZaNoVa ©   (2004-11-14 02:09) [37]

GuAV ©   (14.11.04 2:08) [36]
извиняюсь ..  протупил .. ;(
- у меня уже 5 утра ..  глючу ...


 
GuAV ©   (2004-11-14 02:18) [38]

В прочем я тоже туплю, хоть на Украине только час ночи...
то что begin ... end не принципиально... и так понятно что вызвана вторая функция.

внизу скрина видно то о чём я говорил... а ещё ниже не видно, но поверьте что там ASCIIZ-строка но не string, длины и счёта ссылок нет.


 
kaZaNoVa ©   (2004-11-14 02:23) [39]

GuAV ©   (14.11.04 2:18) [38]
имхо хитрый компилятор всё путает .. ;)


 
iZEN ©   (2004-11-14 02:41) [40]

Напомните, пожалуйста, компилятор TurboPascal/Delphi отлавливает такую ситуацию:

unit Module1;

interface

procedure TestString(var s: String);

implementation

procedure TestString(var s: String);
begin
 s := s + " in Module1";
end;

end.

И ещё один модуль:

unit Module2;

interface

procedure TestString(var s: String);

implementation

procedure TestString(var s: String);
begin
 s := s + " in Module2";
end;

end.

Программа:

program DemoTest;

uses Module1, Module2;

var
 s: String;
begin
 s := "Test String";
 TestString(s);(* Module1.TestString(s) или Module2.TestString(s)??? *)
end.



Страницы: 1 2 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.036 c
1-1100300302
Klopan
2004-11-13 01:58
2004.11.28
Сканер сайта


14-1099845523
ИМХО
2004-11-07 19:38
2004.11.28
Нашел глюк в форуме!


3-1099118308
GURU-RU@bk.ru
2004-10-30 10:38
2004.11.28
Автосохранение БД


1-1100108593
BlackLord2003
2004-11-10 20:43
2004.11.28
Сообщение об ошибках


1-1100637651
Lelik
2004-11-16 23:40
2004.11.28
Открытие файла





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский