Forum > FPC development

TypeInfo() - what is it?

(1/3) > >>

beria:
As I understood, from the point of view of the description - TypeInfo() (https://www.freepascal.org/docs-html/rtl/system/typeinfo.html) is a compiler function, which works only at compile time and returns a pointer to a variable type.  That is, it does not generate any binary code in the program. The nearest analogue of this function which works this way is IsConstValue().
But in reality a simple example shows that it is not so and it generates unnecessary sets of comparing predefined constants with predictable result...
An example for the procedure

 
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure test40(a: ptrUint); inline;  begin    if typeinfo(a) = typeinfo(BYTE) then Writeln('BYTE');  end;
 in the program to call test40(i), where i-ptrUint; in theory there should be no code, as, by the way, IsConstValue() works, generating code, without any conditional overflows, depending on whether the argument is a constant...
I have it generated by calling test40 ...

    ; Register edx allocated
            mov edx,dword RTTI_$SYSTEM_$$_LONGWORD
    ; Register eax,eflags allocated
            cmp edx,dword RTTI_$SYSTEM_$$_BYTE
    register eax,edx released
            jne ..@j235
    ; Register eflags released
    ; Register eax,ecx,edx allocated

Which makes no sense, because they are always compare different constants which are always predefined before the start of the program.

... Or maybe I'm missing something in the implementation of this function, and it's still not an internal compiler function, as it's written in the description, or FPC somehow allows you to change the variable's type, which is totally insane to me?

ASerge:

--- Quote from: beria on November 30, 2022, 03:32:31 pm ---Or maybe I'm missing something in the implementation of this function, and it's still not an internal compiler function, as it's written in the description, or FPC somehow allows you to change the variable's type, which is totally insane to me?

--- End quote ---
According to the link that you yourself indicated, it is written "If no type information was yet generated for the type, this statement will ensure that type information is available, i.e. the result is always non-nil".
Thus metadata is always generated when using TypeInfo.
Use GetTypeKind:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure test40(a: PtrUint); inline;begin  if GetTypeKind(a) = GetTypeKind(Byte) then    Writeln('BYTE');end;

beria:
Thank you very much. I had your option first, and it works and is very good, but it turns out that I think due to an implementation error, ALL integer types, regardless of their size in bytes, which is what I need, are the same for GetTypeKind...
The code below gives the same values.... So this built-in compiler function is a priori for me and my tasks, not working...

writeln(GetTypeKind(byte));
writeln(GetTypeKind(longint));
......

And I don't think you're right about mandatory code generation for TypeOf.... TypeOf() generates, as you can see from the code and description, just the value of the constant, like "Роinter", like IsConstValue() of the constant type "boolean" Nothing else.  And the compiler itself should, in theory, optimize them... But it always works only in the case of IsConstValue() and does not in the case of TypeOf(). I still don't know why I have to make a zoo of functions to decode a binary stream depending on the size of an integer argument in bytes instead of one universal function...

Here is a code sample optimizing constants in FPC:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const  const1 = 1;  const2 = 2;  beginif const1 = const2 then write ('test');end.
This program construction does not insert anything anywhere, neither comparing constants with predefined result, nor calling function "write"..... It should be exactly the same in theory, but it doesn't work...

PascalDragon:

--- Quote from: beria on November 30, 2022, 11:07:43 pm ---Thank you very much. I had your option first, and it works and is very good, but it turns out that I think due to an implementation error, ALL integer types, regardless of their size in bytes, which is what I need, are the same for GetTypeKind...
--- End quote ---

GetTypeKind returns a TTypeKind and for these all integer types are in fact tkInteger. They only differ by the OrdType which is part of the TTypeInfo returned by the TypeInfo intrinsic, but which isn't covered by GetTypeKind. It's intention is to optimize the main lookup of types, not all of them.


--- Quote from: beria on November 30, 2022, 11:07:43 pm ---And I don't think you're right about mandatory code generation for TypeOf.... TypeOf() generates, as you can see from the code and description, just the value of the constant, like "Роinter", like IsConstValue() of the constant type "boolean" Nothing else.  And the compiler itself should, in theory, optimize them... But it always works only in the case of IsConstValue() and does not in the case of TypeOf(). I still don't know why I have to make a zoo of functions to decode a binary stream depending on the size of an integer argument in bytes instead of one universal function...

--- End quote ---

The compiler currently simply does not treat the pointers returned by TypeInfo as constant. FPC 3.3.1 however will at least optimize comparisons between two TypeInfo invocations that contain types:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if TypeInfo(PtrUInt) = TypeInfo(Byte) then Writeln('BYTE')
This will evaluate to False at compile time. I'd need to check whether it is really safe to extend this further.

beria:

--- Quote from: PascalDragon on November 30, 2022, 11:26:43 pm ---
--- Quote from: beria on November 30, 2022, 11:07:43 pm ---


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---if TypeInfo(PtrUInt) = TypeInfo(Byte) then Writeln('BYTE')
This will evaluate to False at compile time. I'd need to check whether it is really safe to extend this further.

--- End quote ---

--- End quote ---

I would say that the safety of such an approach follows directly from the whole paradigm of the Pascal language with a pre-description of all types.... But the procedure below is not working yet because it generates unnecessary code... By the way, for "generics" the same restrictions and code bloat.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure test41(a: ptrUint); inline;  begin    if TypeInfo(a) = TypeInfo(uint8) then Writeln('1')    else if TypeInfo(a) = TypeInfo(uint16) then Writeln('2')    else if TypeInfo(a) = TypeInfo(uint32) then Writeln('4')    else if TypeInfo(a) = TypeInfo(uint64) then Writeln('8');  end;       
ps: there is a hope in the near future to wait at least beta of new functionality, what with pleasure I will test in the real and working project?  I don't think it will be very difficult because, at first glance, I just saw how TypeInfo is implemented in the source code of FPC, just there artificially limited functionality, as opposed to many other built-in compiler functions, which also return a constant.
pps: and on a side note, is there any way for "{$mode objfpc}" to use the simpler and more obvious "generics" syntax from the Delphi compatibility relim, just that I don't use?


Navigation

[0] Message Index

[#] Next page

Go to full version