Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 09/26/21 in all areas

  1. When a TComponent is inserted into another TComponent (like a TButton into a TForm) it tries to connect that component to a published field matching the name of the component. The responsible code part is the SetReference call in TComponent.InsertComponent. That is one reason why the Form Designer adds the component fields as published. Side note: You can even take advantage of this mechanism for your own needs. It is not restricted to the streaming system.
  2. No, it is the name of the variable that contains the object. The name of a TComponent instance can be different from the names of the variables containing that instance.
  3. I am unsure what you expect, but in this code procedure TConcrete.Method(aObjectEvent: TNotifyEvent); begin aObjectEvent(Self) end; the parameter Self represents the instance of TConcrete. As long as you don't give a name to that instance like in this code sequence fBASE := TConcrete.Create(nil); try fBASE.Name := 'My Name'; // give fBASE a name fBASE.Method(Btn_Normal_Event.OnClick); finally fBASE.Free; end; the Name property remains empty. But as I already mentioned in the beginning: It is quite unclear what you expect.
  4. dummzeuch

    Why empty dynamic arrays = NIL?

    In theory you could create a method that checks for self <> nil and only then returns Count, zero otherwise, so the code would look simpler: for i:=0 to List.getCount-1 do Even thought the <> nil check is still there.
  5. 0x8000FFFF

    Why empty dynamic arrays = NIL?

    Isn't that the case for string? When it's empty, it's a pointer to empty, no? An empty string is equal to nil pointer. Try this: var s := ''; Writeln(Format('%p', [Pointer(s)])); One of the differences between arrays and lists is that even empty lists can have pre-allocated capacity. This is often an overlook feature of lists which helps reducing reallocations while populating the list if you know (or can estimate) the count in advance.
  6. Stefan Glienke

    Why empty dynamic arrays = NIL?

    Because a pointer to empty would be quite stupid. While you can technically build an allocated array with a capacity of zero with some hacking the RTL always cleans up the memory as soon as an arrays length becomes 0. Fun fact - checking against nil for the purpose of "is it empty or not" opposed to comparing Length to 0 is slightly faster: procedure test(const a: TBytes); begin if a <> nil then Writeln; if Length(a) > 0 then Writeln; end; CheckArray.dpr.12: begin 0041D57C 53 push ebx 0041D57D 8BD8 mov ebx,eax CheckArray.dpr.13: if a <> nil then 0041D57F 85DB test ebx,ebx 0041D581 740F jz $0041d592 CheckArray.dpr.14: Writeln; 0041D583 A1B4254200 mov eax,[$004225b4] 0041D588 E8CF7DFEFF call @WriteLn 0041D58D E8B270FEFF call @_IOTest CheckArray.dpr.15: if Length(a) > 0 then 0041D592 8BC3 mov eax,ebx 0041D594 85C0 test eax,eax 0041D596 7405 jz $0041d59d 0041D598 83E804 sub eax,$04 0041D59B 8B00 mov eax,[eax] 0041D59D 85C0 test eax,eax 0041D59F 7E0F jle $0041d5b0 CheckArray.dpr.16: Writeln; 0041D5A1 A1B4254200 mov eax,[$004225b4] 0041D5A6 E8B17DFEFF call @WriteLn 0041D5AB E89470FEFF call @_IOTest CheckArray.dpr.17: end; 0041D5B0 5B pop ebx 0041D5B1 C3 ret
  7. corneliusdavid

    Why empty dynamic arrays = NIL?

    To expand on what Uwe said, an array declaration allocates space for the variable and creates it when it's declared, much like an integer or string. Changing it's length sort-of redeclares it. This is in contrast to the TList<T> where the declaration doesn't allocate space for the variable (instantiate it) so you have to actually call its Create constructor. Before it's "created" then, it's nil.
  8. No, it is not a flaw. This is how Delphi (probably even Pascal in general) has always worked. A parameter's default value is required only in the function's declaration. At any site where the function is called, the compiler needs to know what the default value is, if the calling code decides to omit the parameter. Duplicating the default value in the function's implementation is optional. The implementation doesn't care whether the caller omitted parameters or not, because the compiler will have filled in any missing values on the call stack before the implementation is entered.
  9. What's the problem with just saying: Exit(False) instead of using a goto to say: Result := False; Exit;
  10. Remy Lebeau

    Enumeration Type as Parameter

    There are quite a few intrinsic functions that have been around for awhile but are still not documented by Embarcadero, but they are by 3rd parties. For instance, https://stackoverflow.com/questions/30417218/. See https://www.google.com/search?q=delphi+undocumented+intrinsics
  11. Remy Lebeau

    Enumeration Type as Parameter

    You should use the intrinsic GetTypeKind() function instead, eg: constructor TBSCatalogBuilder<T>.Create(ACatalogId: Integer; const AName: String); begin if GetTypeKind(T) <> tkEnumeration then begin raise Exception.Create('Passed type is not an enumeration.'); end else begin FTypeData := GetTypeData(TypeInfo(T)); ... end; end; This way, if T is an enumeration type, the compiler will omit the raise statement from the final executable, and if T is not an enumeration then it will omit the rest of the constructor code leaving just the raise, eg: constructor TBSCatalogBuilder<AnEnumType>.Create(ACatalogId: Integer; const AName: String); begin FTypeData := GetTypeData(TypeInfo(AnEnumType)); ... end; constructor TBSCatalogBuilder<ANonEnumType>.Create(ACatalogId: Integer; const AName: String); begin raise Exception.Create('Passed type is not an enumeration.'); end; The way you wrote the code originally using Assert() does not allow the compiler to make that same optimization.
  12. Daniel

    wuppdi Welcome Page for Delphi 11 Alexandria?

    Not being a MVP anymore, it is the first time in years that I do not have access to a recent version Delphi. But I will have a solution for you. Please give me a couple of days.
×