Is there any Delphi version that can emit RTTI containing tkUnknown?
Asked Answered
P

1

7

Just to make sure I'm not overlooking a strange edge case as I've found yet a case that produce it, but I want to make sure:

Is there any Delphi version that can emit RTTI containing a type that has tkUnknown as TTypeKind?

If so:

  • any documentation reference?
  • what type would produce it?

In the current Delphi XE5 RTL, the only place I could find handling tkUnknown is TValue, but I've not found a code path in the RTL that sets up a TValue containing a TypeInfo having tkUnknown as Kind.

Pruritus answered 1/3, 2014 at 9:10 Comment(11)
The compiler writes the RTTI into the executable surely. So I guess looking in the source won't help 'cos you don't have the relevant source. That said, how could the compiler write out RTTI for a type it did not understand.Flagella
@DavidHeffernan I think the chance is very very slim. Just want to make sure some of the Spring4D parts that handle TTypeInfo data will not barf.Pruritus
Here is a type that produce tkUnknown: TMyEnum = ( a = 1, b = 2 );Sitin
@SirRufo Very good. Do you even need the second enum value?Flagella
aTValue := TValue.Empty; will also produce a tkUnknown.Pereira
@SirRufo Actually you cannot even compile TypeInfo(TMyEnum) so at least in XE (don't have a more recent version available right now) this would not even produce any PTypeInfo. Actually the RTTI is incomplete in these cases so having a field of TMyEnum is not having any TRttiType and methods with a parameter of that type return wrong data when calling TRttiMethod.GetParameters().Weeny
@LURD It only returns tkUnknown when calling GetTypeKind on a TValue that does not contain anything - which also was kinda broken in earlier versions of Delphi (like IsEmpty returned True when it contained a reference type that was nil which resulted in GetTypeKind to return tkUnknown and not the correct TypeKind like tkClass or tkInterface). The GetTypeInfo method returns nil. So actually the answer is no, there is no TypeInfo with TypeKind = tkUnknown. tkUnknown actually means there is no TypeInfo available.Weeny
@StefanGlienke I tested this with XE5 and TValue.From<TMyEnum>( a ) and TValue.Kind was tkUnknownSitin
@SirRufo Well yes because there is no typeInfo as said. Try compiling TypeInfo(TMyEnum) or call ToString on that TValue - I bet it writes '(unknown)'. And that is because of what I said earlier: no type info for TMyEnum. Look at the implementation of TValue.From<T>. I really wonder that it compiles but I guess the compiler just works around this issue by passing nil (debug into TValue.Make and check the passed ATypeInfo).Weeny
@StefanGlienke, aTValue.Kind returns tkUnknown while aTValue.TypeInfo returns nil.Pereira
@LURD Yes, did I say otherwise anywhere? That would have been a mistake then.Weeny
W
8

The answer is no. Anything else would be a bug in the compiler.

tkUnknown is the indication that there is no type info available which might be the case for discontiguous enumerations and enumerations which don't start at zero (as explained by Barry here) and some types from long ago (like Real48).

It also is returned by TValue.Kind when TValue.IsEmpty is true. (since XE2 afaik before it also could return True in cases where it held a reference type that was nil which was a bug).

When you are retrieving RTTI for something that does not contain type info (like a field, property or parameter of a type that has no type info) your RTTI information is incomplete. TRttiField.FieldType and TRttiProperty.PropertyType return nil in these cases and the array returned by TRttiMethod.GetParameters is incomplete.

While it is possible to call TValue.Make<T> with a type that has no type info you will not be able to do much with this because its TypeInfo will be nil. The compiler obviously works around E2134 and passes nil to TValue.Make. Thus TValue.Kind will say tkUnknown.

Weeny answered 1/3, 2014 at 15:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.