1

我想知道 Succ/Prev 内在函数是否应该能够用于类型化指针类型。就像Inc/Dec和数学(PointerVar+1PointerVar-1)一样。

这些仅适用于 succ/pred 未列出其中的点的“序数类型”。Pascal Report 1972 也是如此(称为标量类型)

但是http://www.gnu-pascal.de/gpc/Succ.html#Succ声称“在 Borland Pascal 中定义了 Succ 对指针的应用”。在 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
4

2 回答 2

4

当然不。这是违反语言规则的。这是正式合同SuccPred正在实施(来自ISO/IEC 7185:1990):

成功(x)

从应为序数类型的表达式 x 中,此函数应返回与表达式类型相同的结果(见 6.7.1)。如果存在这样的值,该函数将产生一个序数比表达式 x 大一的值。如果不存在这样的值,则应为错误。

预测(x)

从应为序数类型的表达式 x 中,此函数应返回与表达式类型相同的结果(见 6.7.1)。如果存在这样的值,该函数将产生一个序数比表达式 x 小一的值。如果不存在这样的值,则应为错误。

如您所见,Succ并且Pred仅针对序数类型的参数定义,因此它与指针类型不兼容(由于缺乏固有的序数,根据合同)。

于 2016-10-13T09:02:10.463 回答
1

Afaik TP 不允许任何类型的增量,afaik 甚至在 pchar 上都不允许(在 $pointermath 之前的 Delphi 已经允许)。所以问题对于 TP(分段内存模型!)和 Delphi 是不同的。

succ 和 pred 被定义为对序数进行操作。尽管您可以将整数添加到指针,但当前指针不被视为序数类型。(参见例如序数类型)。

有人可能会争辩说它可能是一种序数类型(delphi 中的指针符合上述链接中的要求),但是一旦您的内存模型被分段,它就不会(因为有多个最小值和最大值)

无论如何,对于 succ 和 pred 都可以例外,但是除了希望工作之外,还有什么意义呢?它不会使以前无法做到的事情成为可能。

于 2016-10-13T07:50:57.523 回答