Leaderboard
Popular Content
Showing content with the highest reputation on 08/29/24 in Posts
-
What does this function mean? CharPrev / Range Check Error
Remy Lebeau replied to terran's topic in General Help
That would not work. That is taking the last character and type-casting its value to a pointer, which is not the same thing as taking a pointer to the last character. I would have used this instead: CharPrev(PChar(S), PChar(S) + Length(S)); That would work with both 0-based and 1-based strings. -
Remy wanted to point out that the WINDOWS or WINAPI unit must not be present in an Android program and that IFDEF is normally used to distinguish Android from Windows (if the program must be multiplatform). Look in the USES of your program and REMOVE all the references to WINDOWS or WINAPI (or use IFDEF in your source to divide the platforms of use and include or not those units.).
-
Custom Managed Records and Default(T)
Stefan Glienke replied to rgdawson's topic in Algorithms, Data Structures and Class Design
There should not be any temp, nor assign call tbh. Check out this code: {$APPTYPE CONSOLE} uses SysUtils; type TMyRec = record x: Integer; class operator Initialize(out dest: TMyRec); class operator Finalize(var dest: TMyRec); class operator Assign(var left: TMyRec; const[ref] right: TMyRec); end; function MyDefault: TMyRec; begin Writeln('default - ', IntToHex(IntPtr(@Result))); Result.x := 0; end; class operator TMyRec.Initialize(out dest: TMyRec); begin Writeln('init - ', IntToHex(IntPtr(@dest))); end; class operator TMyRec.Finalize(var dest: TMyRec); begin Writeln('finalize - ', IntToHex(IntPtr(@dest))); end; class operator TMyRec.Assign(var left: TMyRec; const[ref] right: TMyRec); begin Writeln('assign'); end; procedure Main; var r: TMyRec; begin r := MyDefault; end; begin Main; end. Now we can argue why there is no assign call because we are assigning the result of the MyDefault function to r. But even though we have declared an assign operator it does what it always does with managed return type - passing it as hidden var parameter. I said this before and I say it again - CMR are broken as designed and personally I stay the heck away from them. I remember some years ago there was a question on SO about struct default ctors serving as default initializers and why C# does not have them and I don't remember if it was Jon or Eric explained that it would cause all kinds of trouble. Edit: Ah, here it is: https://stackoverflow.com/a/333840/587106 - eventually they added them in C# 10 but there is quite some extensive language spec - when I asked for the CMR spec it was all crickets. FWIW the Delphi implementation suffers from exactly the situation that Jon describes - allocate a dynamic array of some CMR and watch all the initializers run. Which is completely bonkers - C# 10 does not do any of that for array allocation - see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/parameterless-struct-constructors#array-allocation -
The Winapi.Windows unit is for Windows builds only. If the component is trying to use that unit in an Android build, then its code is not IFDEF'ed properly to separate any platform-specific code, and thus needs to be fixed accordingly.
-
Why are you re-compiling Winapi.Windows.pas? You should not be doing that. In any case, Winapi.Windows.pas declares the _CONTEXT record only if the CPUX64 or CPUX86 conditional is defined. Perhaps they are not defined in your situation?
-
Custom Managed Records and Default(T)
Remy Lebeau replied to rgdawson's topic in Algorithms, Data Structures and Class Design
Maybe I'm just having a brain fart, but why would a new record instance need to be FINALIZED before it is INITIALIZED? The System.Default documentation even states: Finalizing implies destruction, not creation. And if a record contains compiler-managed types (interfaces, strings, dynarrays, etc), finalizing it before initializing it would invoke refcounting semantics on things that aren't valid yet. What am I missing here? -
What does this function mean? CharPrev / Range Check Error
Remy Lebeau replied to terran's topic in General Help
As I stated earlier, PChar(S[Length(S)]) is extracting the last single Char from the string and type-casting its value into a PChar pointer, which is wrong. You need to use the @ operator to get the address of that Char. But in any case, using S[Length(S)] doesn't take into account that a string contains encoded codeunits, so will NOT be the last full character if the character is encoded using multiple codeunits. CharPrev() takes the encoding into account. The code is getting a pointer to the null terminator and then moving the pointer backwards 1 full character regardless of how how many codeunits it actually takes. -
If everyone thinks the others are already doing it, then nothing will happen. So if the error bothers you so much, maybe you should open the RSP. The problem has also stressed me out more, but after uninstalling Bookmarks and Navigator it hardly affects me any more. That's why I haven't bothered to create an RSP. Incidentally, I have always had good experiences with the resolution of my RSP. I also have a support contract. First I create an RSP and then when it is confirmed I report it to support, they have always been able to solve the problem and integrate it into the next version.
-
PLABEL VCL Labelling, FlowChart and Technical Drawing editor
egroups replied to Alberto Fornés's topic in Delphi Third-Party
Hi Alberto,it's great. -
Unable to hide submenu item in TActionMainMenuBar using code
Gord P replied to Gord P's topic in General Help
Now having said that, I just came across a reason why you would want to access the item instead of changing the Action itself. For instance, if you wanted to change the caption of the menu item but you don't want the Action caption changed (say because a different control needs to have the original caption). In this case, accessing the item itself is necessary. This is doable at design time but I can't figure out how to do it at runtime. Anyone have any ideas? edit: Okay I finally figured it out. I was so close. I needed to dynamic_cast it. The correct line is dynamic_cast<TActionClientItem*>(ActionMainMenuBar1->ActionControls[3]->ActionClient->Items->Items[2])->Caption = "Finally!!!"; // or ->Visible = false; -
What does this function mean? CharPrev / Range Check Error
Remy Lebeau replied to terran's topic in General Help
The difference is that: @S[Length(S)+1] returns a pointer to the null-terminator only on a 1-based string, but goes out of bounds on a 0-based string. PChar(S)+Length(S) returns a pointer to the null-terminator on both a 1-based and a 0-based string. Range checking would need to be disabled, because the null terminator is not included in the Length of the string, so it is not an indexable character, even though it is physically present in memory. All the more reason to use pointer arithmetic instead of character indexing to access the terminator. -
Custom Managed Records and Default(T)
Remy Lebeau replied to rgdawson's topic in Algorithms, Data Structures and Class Design
When I run your code, I see your Default() statement is calling Initialize() two times on the same temporary Stringlist instance, then that temporary is Assign()'ed to the Result record, and then the temporary is Finalized() only one time. Clearly one of the Initialize() calls is erroneous. I have reported this to Embarcadero: RSS-1647: System.Default() on a Custom Managed Record calls its Initalize operator too many times -
PLABEL VCL Labelling, FlowChart and Technical Drawing editor
Alberto Fornés replied to Alberto Fornés's topic in Delphi Third-Party
Yes, next week I will start with the version for FMX, the RTL base and the drawing with Skia is the same, the changes are the writing of the editor component. -
it happens sometimes when pressing CTRL+C they keep churning out new versions of delphi, but they don't fix very old bugs! I'm starting to get bored.. sooner or later I'll switch to another language.. I've been using the IDE this way since Delphi 5, it's comfortable for me and I wouldn't want to change.
-
"Death to WITH" in your Delphi Code
Brian Evans replied to Darian Miller's topic in Tips / Blogs / Tutorials / Videos
If they added the ability to provide an alias the ambiguity would be gone. Aliases in SQL are useful and perform a similar function. Shortening repeated references can make code easier to read, the problem is the current WITH creates ambiguity. A code snipped from the blog post redone with the ability to provide an alias as an example: procedure TMyForm.UpdateInventoryItem(const NewQty: Integer); begin with dmStoreInventoryData as A do begin with A.tblUpdateItemForStore as B do begin B.Edit; B.FieldByName('Qty').AsInteger := NewQty; B.Post; end; end; end; -
Custom Managed Records and Default(T)
Stefan Glienke replied to rgdawson's topic in Algorithms, Data Structures and Class Design
Already reported in 2021