Форум: "Потрепаться";
Текущий архив: 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.
← →
iZEN © (2004-11-14 02:49) [41]Проверил тест (iZEN © (14.11.04 02:41) [40]) только что.
Delphi7 НЕ ОТЛАВЛИВАЕТ И КОМПИЛИРУЕТ БЕЗ ПРЕДУПРЕЖДЕНИЙ!!!
Даже не зависит от порядка объявления:
uses Module1, Module2;
и
uses Module2, Module1;
процедура TestString всегда вызывается из Module1.
Вот такая неоднозначность.
← →
iZEN © (2004-11-14 02:58) [42]Причём процедура какого модуля вызовется, зависит от очерёдности создания модулей в проекте Delphi, а не в объявлении uses, что не есть хорошо в плане определения языка. Выходит, что среда Delphi не слабо влияет на язык.
← →
iZEN © (2004-11-14 03:01) [43](iZEN © (14.11.04 02:58) [42])
Какие-то глюки пошли, всё равно вызывается Module1.TestString.
Я ОФИГЕВАЮ.
← →
GuAV © (2004-11-14 03:07) [44]2 iZEN
А может это потому что они перечисленны и в dpr и в модуле ? и где-то перестваил Module2 <-> Module1 а где-то нет ?
← →
iZEN © (2004-11-14 03:15) [45]uses Module1, Module2;
BuildAll, запускаю: Test String in Module1.
Вроде отлично.
Исключаю из проекта Modul1, затираю исходники Modul1, уничтожаю все dcu, убираю в uses ссылку на него: uses Module2;
Project -> BuildAll -> Run: Test String in Module2.
Вроде отлично.
File -> New -> Unit -> редактирую -> SaveAs "Module1"
Добавляю в uses ссылку: uses Module1, Module2;
BuildAll, запускаю: Test String in Module2.
Глюк? (1)
Комментирую в uses ссылку: uses Module1;//, Module2;
Project -> BuildAll -> Run: Test String in Module1.
Отлично.
Меняю местами в uses ссылки: uses Module2, Module1;
Project -> BuildAll -> Run: Test String in Module1.
Глюк? (2)
Что это? Где логика между Глюками (1) и (2)? Лично я не нахожу причин от чего зависит поведение программы.
← →
iZEN © (2004-11-14 03:18) [46]to GuAV © (14.11.04 03:07) [44]
АБСОЛЮТНО нет связи между порядком перечисления и выполнением.
← →
iZEN © (2004-11-14 03:34) [47]В консольном приложении есть связь между порядком перечисления в uses и выполнением: выполняется процедура, объявленная в модуле, стоящим последним в списке uses.
← →
iZEN © (2004-11-14 03:50) [48]В оконном приложении так же.
Так что прошу прощения за "глюки".
← →
Piter © (2004-11-14 14:47) [49]Игорь Шевченко © (14.11.04 1:20) [27]
> И ?
> IMHO это сюда не при чём. TestFunc(string("test")) всё равно
> вызовет PChar функцию.
Я надеюсь, это проверено, и все преобразования аргументов в случае такого вызова можно выложить в студию ?
Игорь, ну а вы опять не верите? Проверено, проверено. Вызывается PChar версия функции...
Игорь Шевченко © (14.11.04 1:23) [29]
делается ли в случае PChar(StringValue) уникальный экземпляз строки.
ух ты, странно что не помните. Не делается, конечно. PChar начинает указывать на первый символ AnsiString - @s[1]
А вот при обратном преобразовании конечно же создается копия, ибо AnsiString никак не может указывать просто на какой-то символ, должна быть еще структура служебная (ну там счетчик ссылок, длина, размер структуры...)
Страницы: 1 2 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.049 c