从语言的角度来看,Succ/Prev 应该适用于指针吗?
From language POV, should Succ/Prev be applicable to pointers?
我想知道 Succ/Prev 内在函数是否应该能够用于类型化指针类型。就像 Inc
/Dec
和数学( PointerVar+1
和 PointerVar-1
)。
- http://docwiki.embarcadero.com/Libraries/en/System.Succ
- http://www.freepascal.org/docs-html/rtl/system/succ.html
这些只适用于 succ/pred 到 "ordinal types" 没有列出其中的一部分。 Pascal Report 1972 也是如此(称之为标量类型)
但是 http://www.gnu-pascal.de/gpc/Succ.html#Succ 声称 "Application of Succ to pointers is defined in Borland Pascal." 并且在 Pointers Math 之后排除这些函数似乎是不合理的。
这个限制是在语言方面得到证实还是只是一个实现问题,看到 Succ/Pred 函数被认为有些神秘?
program Project9; // Delphi does have reverse-analogu for Pos/PosEx functions
{$APPTYPE CONSOLE} // So Delphi IDE ( Version Insight) to cut away a last part
uses // of string abuses mixing of record helper (LastIndexOf)
System.SysUtils; // and System.Copy function. Searchinf to fix it found this...
var
OutPut, RemoteName: string;
P: PChar;
begin
try
OutPut := 'aaaaaa/zzzzzz';
P := StrRScan( PChar(OutPut), '/');
P := Succ(P);
// XE2: [DCC Fatal Error] Project9.dpr(13): F2084 Internal Error: AV0C068241-R00000000-0
// 10.1: [dcc32 Error] Project9.dpr(13): E2008 Incompatible types
P := 1+P; // Another way to say Succ() - and works in both XE2 and 10.1
Inc(P); // Yet one more way to say Succ() - and works in both XE2 and 10.1 too
RemoteName := P;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
有趣的是将它与更改后的 var 类型进行比较 - P: Pointer;
而不是 PChar。
var P: Pointer; S: String;
P := Succ(P); // error
Inc(P); // error
P := 1+P; // works in XE2 if {$POINTERMATH ON}, error if {$POINTERMATH OFF}
// error in 10.1 regardless
S := PChar(P); // crashes XE2 if "P := 1+P;" is there above
Afaik TP 不允许任何类型的增量,afaik 甚至不允许在 pchar 上(Delphi 在 $pointermath 之前已经允许)。所以对于 Delphi.
,TP(分段内存模型!)的问题是不同的
succ 和 pred 被定义为对序数进行操作。尽管您可以将整数添加到指针,但目前指针不被视为序数类型。 (参见 ordinal types)。
有人可能会争辩说它可能是一个序数类型(delphi 中的指针符合上面 link 中的要求),但一旦你的内存模型被分段它就不会(因为有多个最小值和最大值)
也许可以为 succ 和 pred 做一个例外,但是除了希望工作之外还有什么意义呢?它doesn't make anything possible that couldn't be done before.
当然没有。这是违反语言规则的。这是 Succ
和 Pred
正在执行的正式合同(来自 ISO/IEC 7185:1990):
succ(x)
From the expression x that shall be of an ordinal-type, this
function shall return a result that shall be of the same type as that
of the expression (see 6.7.1). The function shall yield a value whose
ordinal number is one greater than that of the expression x, if such a
value exists. It shall be an error if such a value does not exist.
pred(x)
From the expression x that shall be of an ordinal-type, this function
shall return a result that shall be of the same type as that of the
expression (see 6.7.1). The function shall yield a value whose ordinal
number is one less than that of the expression x, if such a value
exists. It shall be an error if such a value does not exist.
如您所见,Succ
和 Pred
仅针对序数类型的参数定义,因此它与指针类型不兼容(由于缺乏固有序数,根据合同)。
我想知道 Succ/Prev 内在函数是否应该能够用于类型化指针类型。就像 Inc
/Dec
和数学( PointerVar+1
和 PointerVar-1
)。
- http://docwiki.embarcadero.com/Libraries/en/System.Succ
- http://www.freepascal.org/docs-html/rtl/system/succ.html
这些只适用于 succ/pred 到 "ordinal types" 没有列出其中的一部分。 Pascal Report 1972 也是如此(称之为标量类型)
但是 http://www.gnu-pascal.de/gpc/Succ.html#Succ 声称 "Application of Succ to pointers is defined in Borland Pascal." 并且在 Pointers Math 之后排除这些函数似乎是不合理的。
这个限制是在语言方面得到证实还是只是一个实现问题,看到 Succ/Pred 函数被认为有些神秘?
program Project9; // Delphi does have reverse-analogu for Pos/PosEx functions
{$APPTYPE CONSOLE} // So Delphi IDE ( Version Insight) to cut away a last part
uses // of string abuses mixing of record helper (LastIndexOf)
System.SysUtils; // and System.Copy function. Searchinf to fix it found this...
var
OutPut, RemoteName: string;
P: PChar;
begin
try
OutPut := 'aaaaaa/zzzzzz';
P := StrRScan( PChar(OutPut), '/');
P := Succ(P);
// XE2: [DCC Fatal Error] Project9.dpr(13): F2084 Internal Error: AV0C068241-R00000000-0
// 10.1: [dcc32 Error] Project9.dpr(13): E2008 Incompatible types
P := 1+P; // Another way to say Succ() - and works in both XE2 and 10.1
Inc(P); // Yet one more way to say Succ() - and works in both XE2 and 10.1 too
RemoteName := P;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
有趣的是将它与更改后的 var 类型进行比较 - P: Pointer;
而不是 PChar。
var P: Pointer; S: String;
P := Succ(P); // error
Inc(P); // error
P := 1+P; // works in XE2 if {$POINTERMATH ON}, error if {$POINTERMATH OFF}
// error in 10.1 regardless
S := PChar(P); // crashes XE2 if "P := 1+P;" is there above
Afaik TP 不允许任何类型的增量,afaik 甚至不允许在 pchar 上(Delphi 在 $pointermath 之前已经允许)。所以对于 Delphi.
,TP(分段内存模型!)的问题是不同的succ 和 pred 被定义为对序数进行操作。尽管您可以将整数添加到指针,但目前指针不被视为序数类型。 (参见 ordinal types)。
有人可能会争辩说它可能是一个序数类型(delphi 中的指针符合上面 link 中的要求),但一旦你的内存模型被分段它就不会(因为有多个最小值和最大值)
也许可以为 succ 和 pred 做一个例外,但是除了希望工作之外还有什么意义呢?它doesn't make anything possible that couldn't be done before.
当然没有。这是违反语言规则的。这是 Succ
和 Pred
正在执行的正式合同(来自 ISO/IEC 7185:1990):
succ(x)
From the expression x that shall be of an ordinal-type, this function shall return a result that shall be of the same type as that of the expression (see 6.7.1). The function shall yield a value whose ordinal number is one greater than that of the expression x, if such a value exists. It shall be an error if such a value does not exist.
pred(x)
From the expression x that shall be of an ordinal-type, this function shall return a result that shall be of the same type as that of the expression (see 6.7.1). The function shall yield a value whose ordinal number is one less than that of the expression x, if such a value exists. It shall be an error if such a value does not exist.
如您所见,Succ
和 Pred
仅针对序数类型的参数定义,因此它与指针类型不兼容(由于缺乏固有序数,根据合同)。