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

Вниз

Передача строки в параметр 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.045 c
2-1194936903
ice321i
2007-11-13 09:55
2007.12.09
Вопрос с запросом


15-1194027609
Черный Шаман
2007-11-02 21:20
2007.12.09
Мы ведем работы по созданию искусственного интеллекта


15-1194605822
boriskb
2007-11-09 13:57
2007.12.09
Это что? Сайт вроде солидный


15-1194549102
Cyrax
2007-11-08 22:11
2007.12.09
Ищу хакеров...


2-1194938145
Layner
2007-11-13 10:15
2007.12.09
DBGrid, 8 знаков после запятой, как?





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