-
Демонстрационный код:procedure test(p: PAnsiChar);
var
ch: AnsiChar;
pch: PAnsiChar;
begin
{1} ch := p[5];
{2} pch := p + 5;
{3} pch := @(p[5]); <-- "[dcc64 Error] E2010 Incompatible types: 'PAnsiChar' and 'Pointer'"
end;
Если не включать опцию компилятора "Typed @ operator" - то этот код компилируется и работает.
Если включить опцию компилятора "Typed @ operator" - то этот код перестаёт компилироваться, ошибка в строке 3, текст в коде.
Почему?
Почему в строе 2 ошибки нет, а в 3 ошибка откуда-то есть?
Может я чего-то не понимаю про оператор [], применённый в дельфи к типизированному указателю?
Проблема есть и в D5, и в D10
Ну и вопрос, конечно, в том, как бы это обойти? какой еще синтаксис можно придумать?
Можно, конечно, использовать синтаксис строки 2, коль скоро он работает. Но мне синтаксис строки 3 видится более понятным, хотелось бы его...
Экспериментировал всяко по-разному, переставлял буквы этой строки во всех возможных последовательностях - ничего не помогает. -
Почему спрашиваю
Потому как, на мой взгляд, в строке 3 написано все верно и все типы сходятся:
- берём пятый элемент относительно указателя типа PAnsiChar
- и берём адрес от этого пятого элемента (символа), адрес 5-го символа.
Результат же должен быть указателем на AnsiChar, т.е. PAnsiChar
Но компилятор с этой моей логикой не согласен, не понимаю почему -
RWolf © (01.03.18 14:30) [2]pch := PAnsiChar(@(p[5]));
-
RWolf © (01.03.18 14:32) [3]
> Результат же должен быть указателем на AnsiChar, т.е. PAnsiChar
> Но компилятор с этой моей логикой не согласен, не понимаю почему
Раз "Typed @ operator" отключено, результат должен быть бестиповым указателем, т.е. Pointer. Отсюда ошибка присвоения. -
Rouse_ © (01.03.18 14:59) [4]Ну каст на PAnsiChar сделай, тож мне задачка
-
> Rouse_ © (01.03.18 14:59) [4]
> Ну каст на PAnsiChar сделай, тож мне задачка
Блин, так я для того и хочу включить "Typed @ operator", чтобы не было ошибок присвоения указателям не того типа.
И тут вдруг кастить.... крайне досадно.
В любом случае благодарю за ответы. -
RWolf © (02.03.18 10:07) [6]Перечитал вопрос, понял ошибку в своих рассуждениях. Мне такое поведение компилятора тоже непонятно.
> какой еще синтаксис можно придумать?
Предлагаю писать pch := Addr(p[5]); -
> RWolf © (02.03.18 10:07) [6]
> > какой еще синтаксис можно придумать?
>
> Предлагаю писать pch := Addr(p[5]);
Дык как раз хотелось защититься от присвоения указателей неправильных типов применением "собачки". Addr убивает всё на корню же с основной задачей )
PS
А еще внезапно наткнулся на то, что Delphi не пишет варнинги на не инициализированные, но используемые переменные. Причем далеко не везде. Во многих местах пишет, а в некоторых - в упор не видит, хотя проблема вот она, явная (проблема даже воспроизводится в run-time, в переменнйо оказывается мусор при определённых условиях), из-за чего проблемные места и были обнаружены.
Пока гипотеза у меня лишь одна: до какого-то количества строк в функции дельфи предупреждения такого рода пишет, а после забивает, типа "сам сделал такую огромную функцию - сам себе злобный буратин" -
У меня Typed @ отключен.
Попробуйте так:
procedure test(P: PAnsiString);
var
ch: AnsiChar;
pch: PAnsiChar;
begin
{1} ch := P^[5];
{2} pch := PAnsiChar(uint64(@P^[1]) + 5);
{3} pch := PAnsiChar(@P^[5]); //<-- Ошибок нет (:
end;
procedure CallTest;
var
A: AnsiString;
begin
A := '0123456789';
test(@A);
end;
А так Delphi вообще большой глюк :)
Но у меня работает.