Форум: "Начинающим";
Текущий архив: 2005.12.25;
Скачать: [xml.tar.bz2];
ВнизConst - параметры функции Найти похожие ветки
← →
gdaujk © (2005-12-10 15:59) [0]Вомногих книгах, да и в справке написано, что кроме запрета на напосредственное изменение const-параметра в теле функции, он ещё и каким-то особенным, "оптимизированным" способом передаётся в функцию (имеются в виду строки и записи). Не объясните, в чём именно состоит оптимизация?
← →
palva © (2005-12-10 16:02) [1]Оптимизация состоит в том, что передается адрес данных. Если const не указано, то адрес данных передавать опасно, поскольку функция может изменить данные. Поэтому приходится копировать данные в отдельную область и передавать адрес этой области, либо передавать сами данные, что тоже накладно.
← →
Ihor Osov'yak © (2005-12-10 16:10) [2]в дополнение.
ключевое слово const в параметрах заставляет следить компилятор за кодом, чтобы не происходило изменения значения параметра в коде процедуры. Хотя это не абсолютная панацея - от изменеия по указателю, либо низкоуровневыми функциями типа move компилятор не защитит.
Оптимизация же в части строк и рекордов состои в том, что вместо выделения буфера на копию и последующем копировании происходит просто передача адреса, то есть засылка 4 байт в стек - то есть намного быстрее.
← →
gdaujk © (2005-12-10 16:13) [3]Мне вот просто кажется, что при передании функци параметра-строки без const тоже передаётся адрес. Только потом, если параметр изменяется, то создаётся копия строки.
Или, возможно, компилятор, если видит, что не-const-параметр в теле функции не изменяется, то организует просто передачу адреса, как как если бы параметр был const. Я прав?
← →
Ihor Osov'yak © (2005-12-10 16:22) [4]2 gdaujk © (10.12.05 16:13) [3]
> Мне вот просто кажется, что при передании функци параметра-строки без const тоже передаётся адрес.
Передается адрес. Все верно. Но уже на копию. Которая создается непосредственно перед передачей адреса. Посмотрите на код, которій генерирует компилятор. делов то на две минуты.
> Или, возможно, компилятор, если видит, что не-const-параметр в теле функции не изменяется, то организует просто передачу адреса, как как если бы параметр был const. Я прав?
Нет, не прав. Ибо дело обстоит не так. А так как Вы говорите - вряд ли на практике кто-то реализует - так как очень сложнымы и неочевидными будут соглашения о передачи параметров в процедуру. Ну, разве что какой-то любитель наступать на грабли будет делать свою реализацию системы прорамирования. Но, обычно, такие любители или вылечиваются до того, или не доживают..
← →
begin...end © (2005-12-10 16:48) [5]> Ihor Osov"yak © (10.12.05 16:10) [2]
> происходит просто передача адреса, то есть засылка 4 байт
> в стек
Почему обязательно в стек?
> Ihor Osov"yak © (10.12.05 16:22) [4]
> Передается адрес. Все верно. Но уже на копию. Которая создается
> непосредственно перед передачей адреса.
Неверно. Копия создаётся не перед передачей адреса, а после его передачи (уже внутри вызываемой подпрограммы).
← →
Ihor Osov'yak © (2005-12-10 17:20) [6]> Почему обязательно в стек?
Если засылка, то в стек :-). Конечно, есть еще передача через регистры, и она имеет место для первіх параметров для определенных моделей вызова, но это уже ньюансы, не отражающиеся на основном сабже..
> Неверно. Копия создаётся не перед передачей адреса, а после его передачи (уже внутри вызываемой подпрограммы).
В принципе - да. Не совсем верно проанализировал код созданный компилятором. Кстати, похоже на то, что все же gdaujk © (10.12.05 16:13) [3] частично прав - если передавать без const и не изменять в процедуре - то там интересные танцы с _LStrAddRef - тохоже, что копия в таком случае тупо не создается.. Хотя сейчас более детально влом разбираться..
← →
jack128 © (2005-12-10 17:47) [7]Ihor Osov"yak © (10.12.05 16:22) [4]
Но уже на копию. Которая создается непосредственно перед передачей адреса.
А каких строках говорим?? Если о длинных, то при передаче по значению происходит увеличение счетчика ссылок, а при передаче по константной ссылке - такого увеличения не происходит. Вот и вся разница. ПО поводу передаче указателя при указании const - то это происходит, только если SizeOf(Параметр) > SizeOf(Pointer).
← →
gdaujk © (2005-12-10 18:22) [8]Передается адрес. Все верно. Но уже на копию.
А мне всё-таки кажется, что не на копию. Приведу пример. Есть функция:function gdaExample(Str: string): string;
var
P: PChar;
begin
P := PChar(Str);
P^ := "A";
Result := Str;
end;
1) вызываю её так: gdaExample("dfdfdfdfdf") - выдаётся ошибка, по видимому - обращение к памяти, выделенной только для чтения.
2) делаю так:Str := "dfdfdfdfdf";
gdaExample("dfdfdfdfdf");
Появляется тоже ошибка.
3) хитрю, делаю так:
Str := "dfdfdfdfdf"; //Str пока только ссылается на "dfdfdfdfdf"
Str := Str + "f"; //а вот сдесь уже выделяется READWRITE память под Str
gdaExample(Str); //нет ошибки
То есть, если бы создавалась копия, она бы была READWRITE и ошибки бы не возникало. Или может это можно как-то по другому объяснить?
PS: опытным путём, понимаишь :-)))
← →
Lamer@fools.ua © (2005-12-10 19:51) [9]>>gdaujk © (10.12.05 18:22) [8]
>То есть, если бы создавалась копия, она бы была READWRITE и ошибки бы не возникало. Или может это можно как-то по другому объяснить?
Можно. Для этого достаточно открыть окно дизассемблера, а также почитать System.pas, раз уж не верите и хотите (не)опытным путём.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2005.12.25;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.013 c