1

I wonder if Succ/Prev intrinsics should be able to be used over typed pointer types. Just like Inc/Dec and maths ( PointerVar+1 and PointerVar-1 ).

These only apply succ/pred to "ordinal types" which pointes are not listed a part of. So does Pascal Report 1972 (calling it Scalar Types)

However http://www.gnu-pascal.de/gpc/Succ.html#Succ claims "Application of Succ to pointers is defined in Borland Pascal." and it seems not reasonable to exclude those functions in the wake of Pointers Math.

Is this restriction substantiated language-wise or just an implementation problem, seeing Succ/Pred functions are seen as somewhat arcane?

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.

Interesting to compare it with changed var type - P: Pointer; rather than 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
Arioch 'The
  • 15,799
  • 35
  • 62

2 Answers2

4

Of course, no. It is against language rules. Here is formal contract Succ and Pred are implementing (from 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.

As you see, Succ and Pred are defined for arguments of ordinal types only, so it is incompatible with pointer types (due lack of inherent ordinality, as per contract).

Free Consulting
  • 4,300
  • 1
  • 29
  • 50
1

Afaik TP does not allow any kind of increment, afaik not even on pchar (which Delphi before $pointermath already allowed). So the question is different for TP (segmented memory model!) as for Delphi.

succ and pred are defined to operate on ordinals. Despite that you can add integers to pointers currently pointers are not considered an ordinal type. (see e.g. ordinal types).

One could argue that it could be an ordinal type (a pointer in delphi adheres to the requirements in above link), but it doesn't as soon as your memory model is segmented (since there there are multiple minimums and maximums)

An exception could be made, maybe, for succ and pred anyway, but what would be the point except a hope work? It doesn't make anything possible that couldn't be done before.

Marco van de Voort
  • 25,628
  • 5
  • 56
  • 89
  • point would be uniformity. Currently there are special rules about three equivalent ways to shift the pointer, some work and some do not. The less special cases the better. – Arioch 'The Oct 13 '16 at 08:04
  • TP7 does allow increment. `procedure Inc(var X [; N: LongInt]);` *X is an ordinal-type variable or a variable of type PChar if the extended syntax is enabled and N is an integer type expression.* – LU RD Oct 13 '16 at 08:14
  • Arioch: no adding it would still not be orthogonal, since adding a hack workaround still doesn't make pointer a full orthogonal ordinal type. It merely masks the problem. LU RD: correct, my bad it doesn't allow p+1 etc in expressions, but does allow inc. – Marco van de Voort Oct 13 '16 at 08:42
  • @Arioch'The: FWIW, a pointer is a *scalar type* (so are floating point types), but it is not an *ordinal type*. `Succ` and `Pred` don't work on floating point types either, so I don't quite see why they should work on pointers. And if they do, should the increment/decrement be scaled by the size of the base type, or should it simply be *one*? ISTM that it raises more questions than it would solve. – Rudy Velthuis Oct 13 '16 at 10:21
  • IIRC, Turbo/Borland Pascal 7 did allow `Inc` and `Dec` for `PChar`s, if the `{$X+}` option (eXtended syntax) was set. – Rudy Velthuis Oct 13 '16 at 20:55