Текущий архив: 2007.12.09;
Скачать: CL | DM;
Вниз
Передача строки в параметр PChar Найти похожие ветки
← →
KSergey © (2007-11-12 08:47) [0]Имеем процедуру:
procedure SomeProc(AStr: PChar);
Вызываем ее так:SomeProc("SomeString");
Компиялтор не ругается и вроде даже все работает (т.е. в ыункция приезжает то, что и ожидалось и в строке внутри процедуры завершающий нуль присутствует). Но по косвенному признаку вдруг закралось подозрение: все ли тут хорошо?
Что собственно беспокоит:
1) Действительно ли корректно передавать строку в параметр PChar без явного преобразования PChar("SomeString")? Я понимаю, что это предбрпзование отчасти фейковое и вроде явного вызова какой-либо процедуры не происходит, но все же?
2) Всегда ли строки в дельфи хранятся с завершающим нулевым символом?
Я понимаю, что "практика - критерий истины", но может кто подскажет место, где эти моменты явно написаны? Куски кода, формирующего строки, например - вполне подойдут.
← →
Anatoly Podgoretsky © (2007-11-12 09:02) [1]> KSergey (12.11.2007 08:47:00) [0]
1. Зачем преобразовывать PChar в PChar?
2. О каких строках речь?
← →
Сергей М. © (2007-11-12 09:04) [2]1. Абсолютно корректно.
2. Смотря как строка объявлена.
← →
KSergey © (2007-11-12 09:07) [3]> Anatoly Podgoretsky © (12.11.07 09:02) [1]
> 1. Зачем преобразовывать PChar в PChar?
Вот это не понял. В смысле - компилятор и так догадается?
← →
KSergey © (2007-11-12 09:10) [4]> Anatoly Podgoretsky © (12.11.07 09:02) [1]
> 2. О каких строках речь?
> Сергей М. © (12.11.07 09:04) [2]
> 2. Смотря как строка объявлена.
Тут меня интересуют 2 варианта (пишу буквально вызовы)://--- Вариант 1 ---
SomeProc("SomeString");
//--- Вариант 2 ---
var S: String
.....
SomeProc(S);
← →
Anatoly Podgoretsky © (2007-11-12 09:35) [5]
> В смысле - компилятор и так догадается?
Ему догадываться не надо, когда это явно указано в прототипе.
По вариантам, во втором надо преобразование, по терминологии приведение.
← →
Однокамушкин (2007-11-12 09:47) [6]Строковые литералы явно приводить к PChar не только не нужно, но даже вредно: в случае литератлов из нескольких символов вы получаете абсолютно такой же код, в случае литерала из одного символа вы получаете access violation... Попробуйте вызвать процедуру вот так SomeProc(PChar("A")) - будет AV... прикол в том, что когда односимвольный литерал используется без явного приведения к типу PChar, компилятор по типу формального параметра понимает, что здесь требуется строка и рассматривает литерал как строковый, а когда между литералом и функцией появляется прослойка в виде приведения типа, компилятор не может оперделить, строковое значение здесь требуется или символьное, и рассматривает односимвольный литерал как символ... Приведение такого литерала к типу PChar призводится так же, как и любого порядкового типа к любому указателю, т.е. берётся численное значение и делается указатель с таким адресом, т.е. например, если литерал равен "A", код этого символа 65 (он же $41), PChar("A") даст вам указатель $00000041, а любые манипуляции с таким указателем приводят к AV
Что касается переменных типа string, то их приведение к PChar обязательно, компилятор по-другому просто не понимает
← →
Сергей М. © (2007-11-12 09:53) [7]
> //--- Вариант 1 ---
> SomeProc("SomeString");
При компиляции под строку "SomeString" будет выделен блок (включая терминирующий #0) в секции иниц.данных модуля, адрес начала блока передан параметром при вызове процедуры. Этот адрес и есть ничто иное как неявный pchar-указатель.
> //--- Вариант 2 ---
> var S: String
> .....
> SomeProc(S);
Такую конструкцию компилятор не пропустит из-за ее неоднозначности, поэтому требуется приведение типа:
SomeProc(PChar(S))
Такая конструкция инструктирует компилятор рассматривать в кач-ве pchar-параметра начальный адрес буфера строки.
← →
KSergey © (2007-11-12 10:01) [8]Всем спасибо за разъяснения. Вопрос снят.
← →
Однокамушкин (2007-11-12 10:19) [9]
> Сергей М. © (12.11.07 09:53) [7]
> При компиляции под строку "SomeString" будет выделен блок
> (включая терминирующий #0) в секции иниц.данных модуля,
> адрес начала блока передан параметром при вызове процедуры.
> Этот адрес и есть ничто иное как неявный pchar-указатель.
Не знаю, как в других версиях Delphi, а в семёрке память для строковых литералов выделяется не в секции иниц.данных, а прямо в секции кода, сразу после той процедуры или функции, в которой этот литерал встретился... Впрочем, мы с вами уже спорили по этому вопросу
← →
Anatoly Podgoretsky © (2007-11-12 10:22) [10]> Однокамушкин (12.11.2007 10:19:09) [9]
Это так, поскольку это константа и ее помещают в константную область, в данном случае кода или его заменителся. Программист не имеет право изменять ее значение.
← →
KSergey © (2007-11-12 11:35) [11]> Anatoly Podgoretsky © (12.11.07 10:22) [10]
> Это так, поскольку это константа и ее помещают в константную
> область, в данном случае кода или его заменителся. Программист
> не имеет право изменять ее значение.
Во-во. На то и напоролися :)
Одно не понятно: версия дельфи не менялась, равно как и UPdates не ставились, а такая "трабла" вылезла...
Есть подозрение на изменившиеся свойства проекта.
← →
Anatoly Podgoretsky © (2007-11-12 11:51) [12]Тебе не кажется смешным изменять константу? Это только Борланд пошел на такие извращения.
← →
KSergey © (2007-11-12 12:10) [13]> Anatoly Podgoretsky © (12.11.07 11:51) [12]
> Тебе не кажется смешным изменять константу? Это только Борланд
> пошел на такие извращения.
Да я все понимаю.
Но проект в таком виде работал до меня не один год, и менял(?) себе константы преспокойно, а тут пришел я - и оно начало ломаться. Может и смешно, но досадно ведь.
← →
guav © (2007-11-12 12:20) [14]> Это только Борланд пошел на такие извращения.
Не только Борланд, с литералами и в С проблемы.#include <string.h>
int main(void)
{
char str1[] = "hello world !";
char * str2 = "hello world !";
strcpy(str1, "that"s okay");
strcpy(str2, "crash"); // здесь пытаемся писать в константный буфер.
}
> [13] KSergey © (12.11.07 12:10)
Может раньше была вин98 или другая старая система, где можно было ?
← →
Anatoly Podgoretsky © (2007-11-12 12:21) [15]> KSergey (12.11.2007 12:10:13) [13]
Чтобы не было смешно - изучаем теория, хотя бы в части Константы
← →
Anatoly Podgoretsky © (2007-11-12 13:04) [16]> guav (12.11.2007 12:20:14) [14]
Я не про эти извращения, здесь все понятно - недостаточные знания.
Я про такие
const
Name = X;
Name := NewX
Страницы: 1 вся ветка
Текущий архив: 2007.12.09;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.037 c