Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.014 c
2-1133955788
_Lucifer_
2005-12-07 14:43
2005.12.25
Передача процедуры как параметра процедуры


5-1117800518
Priest
2005-06-03 16:08
2005.12.25
Не работает оператор is для класса в Dream Designer


4-1130121564
Symbol
2005-10-24 06:39
2005.12.25
Драйвер виртуального устройства


9-1122462101
Kerk
2005-07-27 15:01
2005.12.25
Описание игры


2-1134384927
De1uxe
2005-12-12 13:55
2005.12.25
Работа с битовыми образами





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский