views:

139

answers:

2

My plan is to make a function that retrieves the highest element of an object, so to speak, the upper range of an array.In other words,I'm trying to get the the code of the function High().

What I have tried so far:

 function High2(var X):integer;
 begin
   Result:=Pbyte(Cardinal(@X)-1)^-1;
 end;

The function above should read the value(length) before the position of the first element in the object(array/string) and return it decreased by 1.However It doesn't retrieve correct results neither on static nor dynamic array type.

How do I recreate the High() function in Pascal?

+4  A: 

Not sure why you'd want to do that when Delphi already has a built-in High() compiler magic function, but OK, here goes.

Static arrays: Can't be done. No size information is stored at runtime since the size is known to the compiler and can't change. High() just drops the necessary number into the code as a constant.

Dynamic arrays: The compiler translates High to a call to DynArrayHigh in the System unit, which returns DynArrayLength - 1. DynArrayLength steps back 4 bytes from the start of the array (you're only stepping back 1) and returns the length as an integer instead of a byte.

Hope this is helpful. Why aren't you just using High, BTW?

Mason Wheeler
FWIW, in Delphi 2010, the extended RTTI actually does store the number of elements (flat) in static arrays, even if the array is not of a managed type. It's necessary for heap tracing.
Barry Kelly
Of course, that data is not co-located with the static array data, so without a generic inference, or other way of passing along the associated PTypeInfo, it won't help.
Barry Kelly
@Mason Wheeler, I'd like to use in Turbo pascal,which is very old and I'm not sure if it has the High() function,that's why I asked.
John
John, Turbo Pascal has the `High` function — check the documentation — but it doesn't have dynamic arrays, so you'll have nothing interesting to call it on. If you want to define dynamic-array-like things in Turbo Pascal, go ahead, but you don't need to duplicate the Delphi code since you'll be in charge of how the length is stored as well as how to retrieve it.
Rob Kennedy
+5  A: 

The High() (and Low()) functions are referred to as "standard functions" which means they're intrinsic to the compiler. Like Write and Writeln, they don't really exist as normal Pascal function declarations. The compiler ensures that they are in the "System" unit scope merely as a convenience and to allow function of the same name within other scopes. This also allows you to qualify them by using System.High() to explicitly reference the System unit version. Since they are intrinsic, the compiler will automatically generate the proper code sequence for the type being considered. This also means that trying to duplicate the full functionality of them is nigh impossible. Just stick with the intrinsic standard functions.

Allen Bauer
+1 excellent answer ;).
RRUZ
Allen exist a document that describes and details the functions that are part of the "compiler magic" group as High, Low, Writeln, etc?
RRUZ
Rruz, the Delphi documentation describes those functions. There's nothing that details how they work, though, because that information is none of your business, being an implementation detail that's liable to change with any Delphi release.
Rob Kennedy