-
Это баг или фича? fpc 1.0.10
Режим ДельфиСовместимости:
function Func(const S : string):string; begin Result := S; pchar(Result)^ := succ(pchar(result)^); end;
var I : integer; begin for I:=1 to 3 do WriteLn(Func('12345 ')); ReadLn; end.
Output 22345 32345 42345
Почему? В Дельфи этот код работает так, как задумывалось.
-
Впечатление, что Delphi и FPC по-разному работают с константными параметрами-строками и/или приведением string>pchar. Однако стОит ли называть это багом? Дело в том, что и разные компиляторы Delphi работают с такой конструкцией по-разному. Я вот сейчас прогнал код под D6 и D3. И вот результат.
Delphi 6: 22345 22345 22345
Delphi 3: Runtime error 216 at 0000381A
Значение {$T} и {$J} на эти различия не влияет.
Конечно, можно обсудить эту несовместимость на форуме разработчиков FreePascal. Но только если после сопоставления компиляторов Delphi у тебя осталось чувство, что эти различия нуждаются в устранении. Так что жду ответа.
-
> Конечно, можно обсудить эту несовместимость на форуме разработчиков > FreePascal. Но только если после сопоставления компиляторов > Delphi у тебя осталось чувство, что эти различия нуждаются > в устранении. Так что жду ответа.
Конечно, пусть даже и по-разному понимается result:=S (дельфи заводит на result, определив, что S - это константа, новую строку и переписывает в нее содержимое S). Т.к. результат-то функции уже не обязан быть константой - это НОВАЯ строка.
pchar(string) они понимают как раз одинаково. Но в любом случае в коде после fpc портится константа. А в дельфи, например такой код:
var S : string;
S := '1234'; pchar(S)^ := '2';
просто даст AV. Ну нельзя константы править!
а S[1] := '2'; проедет нормально, т.к.
When indexing is used to change the value of a single character in a string, a copy of the string is made if—but only if—its reference count is greater than one. This is called copy-on-write semantics.
-
Я отправил этот пример (не в buglist, а только в mailing list), хотя так и не уверен в катастрофичности этой фичи (или бага). По такой логике, нельзя работать, например, и вот так:
{$J+} const x:integer=1; procedure proc(var x:integer); begin writeln(x); inc(x); end; var i:integer; begin for i:=1 to 3 do Proc(x); end.
А этот пример btw работает и в Delphi.
-
И вот это тоже работает и в FPC, и в Delphi одинаково. {$J+} procedure proc; const x:integer=1; begin writeln(x); inc(x); end; var i:integer; begin for i:=1 to 3 do Proc; end.
-
2Verg: Тем не менее, Jonas Maebe из команды FPC согласился именно с тобой, а не со мной :^).
-
> const > x:integer=1;
Нет я имел ввиду даже не те константы, которые просто указаны как const c : type = value; А неявные константы. WriteLn('12345') - здесь '12345' - неявная константа, которая вообще для надежности компилером должна быть размещена в секции кода, чтобы автоматичекси исключить их изменение. А насчет copy-on-write про string-и - это я считаю абсолютно верно сделано в Дельфи От чего у меня такой вопрос возник вообще: Требовалось реализовать:
function ToOem(const S : string):string; begin result := S; if S<>'' then CharToOem(pchar(result), pchar(result)); // Windows ф-ция // Допускающая inplace конвертацию для ansi end;
-
2Verg: Может, для порядка свой пример поместишь в список багов на сайте www.freepascal.org?
-
> PVOzerski © (16.04.04 12:21) [7]
Возможно.
Кстати, еще один вопрос, раз уж речь пошла про константы: Как в fpc правильно написать:
const SomeWideText : PWideChar = 'SomeWideText';
В Дельфи это прокатывает "наура", а fpc....
Может я что забыл?
-
Тоже повод написать багрепорт. Я проверил на довольно свежем 1.9.3 - не хочет. А вот WideString понял. Но с ветвью 1.0 могут быть проблемы и с widestring.
|