-
Content Count
1428 -
Joined
-
Last visited
-
Days Won
141
Everything posted by Stefan Glienke
-
Google Tests (unit testing framework) working with Embarcadero C++ clang compiler?
Stefan Glienke replied to Roger Cigol's topic in General Help
The demand is being able to compile the existing framework š- 26 replies
-
- c++
- google tests
-
(and 1 more)
Tagged with:
-
Google Tests (unit testing framework) working with Embarcadero C++ clang compiler?
Stefan Glienke replied to Roger Cigol's topic in General Help
DUnit is not actively being maintained, true. But I am planning to keep on using it - it achieved a nice balance between being flexible enough but at the same time very simple and not overengineered, ymmv. I don't care what some guy in that issue says - they have been doing modifications to DUnit themselfes for ages and suddenly its a DUnit issue they cannot/don't want to fix? How ridiculous tbh. I have my opinion about DUnitX - but it's certainly not deprecated but Vincent does not care for adding C++ support afaik. I was in fact looking into dusting off DUnit, removing old cruft like the CLR stuff and applying some optimizations such as making parameters const, reducing unnecessary overhead in Check methods and so on (doing so improves the overall runtime of my tests by like 10% simply because the CheckSomething methods are faster!) while doing that I could look into making it work with C++- 26 replies
-
- c++
- google tests
-
(and 1 more)
Tagged with:
-
Google Tests (unit testing framework) working with Embarcadero C++ clang compiler?
Stefan Glienke replied to Roger Cigol's topic in General Help
Out of interest - and possibly even making sure that TestInsight works with C++ using DUnit (no promise though) - what does not work with DUnit in C++?- 26 replies
-
- c++
- google tests
-
(and 1 more)
Tagged with:
-
Range Check Error ERangeError
Stefan Glienke replied to david_navigator's topic in RTL and Delphi Object Pascal
What exactly is strange about it? They changed WPARAM from INT_PTR to UINT_PTR in XE2. The point is that the hint still does not show the actual alias name being used in the declaration of the routine but the actual type it aliases. And that is wrong because that causes these kinds of defects when the alias changes because people of course did a cast to the type being shown in code insight. -
Range Check Error ERangeError
Stefan Glienke replied to david_navigator's topic in RTL and Delphi Object Pascal
Don't blame the developer - blame the poor hints - taken from Delphi XE and 10.4: Before anyone tells me to report it - been there, done it! https://quality.embarcadero.com/browse/RSP-17110 The cast to Integer is indeed wrong - see the assembly code with Bounds checking enabled: Unit2.pas.31: PostMessage(Handle, CM_SEARCH, Integer(Sender), Key); 0060F70F 8B45F4 mov eax,[ebp-$0c] 0060F712 0FB700 movzx eax,[eax] 0060F715 50 push eax 0060F716 8B45F8 mov eax,[ebp-$08] 0060F719 85C0 test eax,eax 0060F71B 7905 jns $0060f722 0060F71D E80686DFFF call @BoundErr 0060F722 50 push eax 0060F723 6800CA9A3B push $3b9aca00 0060F728 8B45FC mov eax,[ebp-$04] 0060F72B E8406EF4FF call TWinControl.GetHandle 0060F730 50 push eax 0060F731 E82A67E0FF call PostMessage With cast to WPARAM: Unit2.pas.31: PostMessage(Handle, CM_SEARCH, WPARAM(Sender), Key); 0060F70F 8B45F4 mov eax,[ebp-$0c] 0060F712 0FB700 movzx eax,[eax] 0060F715 50 push eax 0060F716 8B45F8 mov eax,[ebp-$08] 0060F719 50 push eax 0060F71A 6800CA9A3B push $3b9aca00 0060F71F 8B45FC mov eax,[ebp-$04] 0060F722 E8496EF4FF call TWinControl.GetHandle 0060F727 50 push eax 0060F728 E83367E0FF call PostMessage To reproduce try enabling top down memory allocation in your windows which will cause the Sender pointer to be large enough that it will be negative when cast to Integer -
Google benchmark also uses GetProcessTimes - here is an article about the differences. And there you can also see why benchmark does a certain number of iterations on the profiled code to ensure a certain overall duration (the number of iterations dynamically depends on the single duration of the measured code) - as you can also see in the presentation from Chandler I linked earlier Another consideration with all these methods is once you benchmark multithreaded code the wall time might not be the information you want.
-
First line of Code Insight not selected (10.4.2)
Stefan Glienke replied to FaFaFooey's topic in Delphi IDE and APIs
I tried this on two different installations with all kinds of different options set for CodeInsight and it always works. Both were on Windows 10 though so it could be an OS thing or interfering with some other third party plugins (I remember cnPack interfering with CodeInsight before) -
For microbenchmarking you don't need that high of a precision - you simply run the benchmarked function thousands of times and then divide by the number of runs and you got your duration. Watch some videos by Chandler Carruth like these two:
-
Spring4D GroupBy First question
Stefan Glienke replied to Epo's topic in Algorithms, Data Structures and Class Design
Then how about you describe what you are trying to achieve? -
Spring4D GroupBy Second question
Stefan Glienke replied to Epo's topic in Algorithms, Data Structures and Class Design
Yes but beware this will be very nasty - thanks to poor type inference in Delphi. You have to use the GroupBy overload with 4 generic parameters: type TGroup = record AppName: string; Groups: IEnumerable<IGrouping<string,TVariable>>; end; var GroupedTwoLevels: IEnumerable<TGroup>; begin GroupedTwoLevels := TEnumerable.GroupBy<TVariable, string, TVariable, TGroup>(IEnumTV, function (const v: TVariable): string begin Result := v.AppName; end, function (const v: TVariable): TVariable begin Result := v; end, function (const key: string; const vars: IEnumerable<TVariable>): TGroup begin Result.AppName := key; Result.Groups := TEnumerable.GroupBy<TVariable, string>(vars, function(const v: TVariable): string begin Result := v.PrjName; end); end); ListBox5.Clear; for var g1 in GroupedTwoLevels do begin ListBox5.Items.Add(g1.AppName); for var g2 in g1.Groups do begin ListBox5.Items.Add(' ' + g2.Key); for var v in g2 do ListBox5.Items.Add(' ' + v.AppName + '_' + v.PrjName); end; end; -
Spring4D GroupBy First question
Stefan Glienke replied to Epo's topic in Algorithms, Data Structures and Class Design
The culprit here is a different one: in 1.2.4 Shuffled caused a shuffle of the input sequence when being called while 2.0 does it every time when the enumerator is being used (internally or externally) ElementAt for example does it - that means during your loop to print items to ListBox2 they are reshuffled every time and then the nth element is being picked by MoveNext n times. And then again the shuffle is triggerd one time for the iteration being done by GroupBy. This follows the implementation in MoreLinq where this was taken from originally. If you want to shuffle but reuse the order then either do TCollections.CreateList(source.Shuffled) or TCollections.CreateList and then call Shuffle on that list. Also I advice against using index based loops and ElementAt on IEnumerable - this will be O(nĀ²) as many sequences are lazy evaluated and cause enumeration every time you call ElementAt. When you fix this you will notice the output of GroupBy between 1.2.4 and 2.0 is exactly the same -> ordered by the appearance of the items in the source. -
Help with dynamic record memory leak
Stefan Glienke replied to Gary's topic in Algorithms, Data Structures and Class Design
Dynamically allocating records and then not storing them as reference won't work because you just create memory to then do a value copy once you add the item to the list making the dynamically allocated memory useless. I suggest you read up on the difference between value and reference types - I am sure there is a chapter about that in Object Pascal Handbook by Marco Cantu which should be available for free to you as owner of Delphi 10.4 -
Help with dynamic record memory leak
Stefan Glienke replied to Gary's topic in Algorithms, Data Structures and Class Design
- you allocate memory but don't dispose it - calling Clear on a value type that is being returned from the list in a for in loop won't do anything on the item still being stored in the list. There is no point in dynamically allocating those records and then storing them as TReminderItem. Either don't allocate and work with TReminderItem (but then you cannot change the fields on values stored in the list - value type semantics), or store as PReminderItem and think of disposing them. Or simply make TReminderItem a class and use TObjectList<T> which will take care of freeing them. -
I doubt - google benchmark is a little more than "run this stuff in a loop and time it with a stopwatch" š
-
I wish someone with some C++ knowledge would write a Delphi wrapper for Google Benchmark
-
LATEST INTEL PERFORMANCE LIBRARIES
Stefan Glienke replied to RDP1974's topic in RTL and Delphi Object Pascal
I am really trying hard to like that stuff but you are not making it easy - why always provide precompiled dlls and not the projects and instructions to do so myself? That would also make it easier to look into issues - there for example seems to be some issue with your libraries, I added D64TBB and D64IPP to my tests project and I get everything from all tests green, over some tests spuriously failing with changing errors to the process just silently dying at some point. (Spring4D, latest develop, in case you want to look into that yourself) - when the tests succeed btw they take approx 10-20% longer than with default MM/RTL. -
How to create an object instance from its class name?
Stefan Glienke replied to Incus J's topic in RTL and Delphi Object Pascal
Yes, it uses RTTI because it does not require the existence of a virtual ctor and can work with parameters as well - if you can go with Remys approach and change your class architecture, then please go with that. -
How to create an object instance from its class name?
Stefan Glienke replied to Incus J's topic in RTL and Delphi Object Pascal
Take a look into TActivator.CreateInstance (typename needs to be fully qualified including unit name) -
You know that annoying person constantly interrupting and asking you the status of some very busy task you are performing? That person is called Application.ProcessMessages
-
Browsing path != the directories I want to index - also browsing path unfortunately does not work recursively and I will not add a million directories to browsing path just to be able to index our company source code which requires one line in the UsesHelper options. I kindly suggest you install the plugin yourself and try it out, experiencing it yourself probably works best - I am not trying to sell you a product or compete with GExperts, I am just sharing something I found valuable and know that people using it (who also use GExperts btw) love it. If you aim for improving the GExperts experience please feel free to do so. Also they complement each other - like UsesHelper currently complains if the unit is already in a uses but you want to move it up or down - well then GExperts comes to the rescue. But for quickly coding away with as little intrusion as possible UsesHelper is just way better imho.
-
Please vote if you think the compiler could help us writing more robust code: https://quality.embarcadero.com/browse/RSP-33504
-
Improving type safety
Stefan Glienke replied to Stefan Glienke's topic in RTL and Delphi Object Pascal
Search for UNSAFE_CAST in QP and you'll find some issues that report all the bogus this produces - maybe after fixing those it might be somewhat usable. If that can avoid introducing yet a new warning type - I am all for that option. -
Yeah, not gonna work - my search paths don't include much pas files. Takes 3 seconds to list System.Classes when I type TStringList (every time!) - and thats with an SSD - too slow. Uses Clause Manager has its use (personally I am never using it) but for that specific task its just too cumbersome for my taste. UsesHelper is an addition to the toolbox and focuses on one thing to do that as simple and efficient as possible and also has its potential drawbacks of possibly running out of sync as the index is not being built every time. But as I see it the code being indexed is mostly library code that does not change anyway - all units explicitly part of a project are indexed every time.
-
Maybe the fact that I just can hit a shortcut and press enter in less than a second to add a uses without completely being disturbed by that UI? It's just a different mindset - I loved the way Visual Studio handled this with their quick action system and wanted it like that in Delphi as well. Maybe I am missing something but tell me the steps to add the containing unit once I declare a variable of type TWuppdi with GExperts. With UsesHelper while on TWuppdi I press Ctr+Shift+A Enter and the unit is in the uses.
-
Delphi ignores path to unit in .dpr
Stefan Glienke replied to Vandrovnik's topic in RTL and Delphi Object Pascal
The order the compiler uses to find units is not the issue - the issue is that the compiler silently ignores the explicitly stated path to the source file in the uses clause of the dpr. And even if it has been the case since the dawn of time - does anyone really think that is a feature worth to have "I know you told me the file has to be at this exact location. But it was not so I just ignore it and look somewhere else, k?" Applying the principle of least astonishment to how the compiler deals with this situation would be to raise an error and tell the user that the file was not found where it was supposed to be. I am very sure this is more helpful than simply ignoring this information and look somewhere else to produce a successful compilation. In fact I even believe this is one of the many cases that lead to those dreaded dcu outdated errors because when you compile a pas the produced dcu is being put into the unit output directory. If you now move around your pas file but miss to change the path in the dpr/dpk because you don't do it in the IDE you might still succeed compiling because now the compiler uses the dcu from the output directory until things go out of sync and the dcu is outdated. Edit: I just tested this and unless the output dir is explicitly listed as search path this situation does not happen *unless* the unit is still open in the IDE regardless its existence in the file system.