从语言POV开始,Succ / Prev应该适用于指针吗?

时间:2016-10-12 21:25:18

标签: delphi pascal freepascal turbo-pascal

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

这些仅将succ / pred应用于"序数类型"哪些指针未列入其中。 Pascal报告1972(称之为标量类型)也是如此

然而http://www.gnu-pascal.de/gpc/Succ.html#Succ声称" Succ在指针中的应用在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

2 个答案:

答案 0 :(得分:4)

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

  

succ(x)

     

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

     

预解码值(x)的

     

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

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

答案 1 :(得分:1)

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

succ和pred被定义为在序数上运作。尽管你可以向指针添加整数,但是当前指针不被视为序数类型。 (参见例如ordinal types)。

有人可能会认为它可能是一个序数类型(delphi中的指针符合上面链接中的要求),但是只要你的内存模型被分段(因为有多个最小值和最大值)就不会这样做

或许,对于succ和pred来说可能会有例外,但除了希望之外,还有什么意义呢?它doesn't make anything possible that couldn't be done before.