-
Content Count
1111 -
Joined
-
Last visited
-
Days Won
96
Everything posted by Dalija Prasnikar
-
I got bitten by an interface!
Dalija Prasnikar replied to Clément's topic in Algorithms, Data Structures and Class Design
You are experiencing classic issue of "mixing objects and interfaces" Your TBaseFrame class has enabled reference counting and you are using it like normal class. You should store it in interface reference - fBaseFrame: IInterface (or whatever other interface type suits you the best) and you should not call Free on it (you cannot call it on interface, but point is that its memory will be automatically handled so you don't have to worry about it) https://dalijap.blogspot.com/2018/03/dont-mix-objects-and-interfaces.html -
1 error + 1 error = 3 errors? where is the extra one?
Dalija Prasnikar replied to c0d3r's topic in Delphi IDE and APIs
Is attention to details useful? Yes. But also context matters. How useful is rearranging the chairs on Titanic? -
Gain with any messaging system is decoupling, so it makes sense to use it even if you make synchronous calls. But in multithreading scenarios, you need full fledged thread safe system capable of posting messages to a queue. In other words, asynchronous messaging. Anything else is just a crutch that can be used only in most simple scenarios.
-
Yes, it can be harder to track from where message originated, but synchronous executing will make your thread wait twiddling thumbs while code runs in the context of the main thread. That is why posting messages is preferred. Of course, everything depends on the particular application and code and whether you can afford performance drop or not.
-
atomic setting of a double variable
Dalija Prasnikar replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
How about http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SyncObjs.TInterlocked.Exchange -
Add support for High-DPI gdiScaling
Dalija Prasnikar replied to Tom Mueller's topic in Delphi IDE and APIs
You can call it whatever you like, but if the fact that MS didn't bother to update MDI window style to match their latest (now 5 years old) Windows 10 OS does not qualify as being deprecated, then I don't know what deprecated is. Also MS is spreading that FUD for the last 25 years... -
Add support for High-DPI gdiScaling
Dalija Prasnikar replied to Tom Mueller's topic in Delphi IDE and APIs
In addition to what @David Heffernan said https://docs.microsoft.com/en-us/cpp/mfc/sdi-and-mdi?view=msvc-160 -
Me, too. But complexities often come with additional features. And often simple systems do not have all the needed features, so when you need them, you can either write your own thingy that only has features you need, or you can use existing more complex one that has features you need plus some more.
-
That is fine. Point is that System.Messaging is not thread safe. If you are writing multi-threaded application and you need to communicate using some messaging system, then System.Messaging will simply not work in such conditions. You can still use it to send messages to the main thread, but you need to synchronize messaging code, which is not always viable solution. In multithreaded applications, you will need thread safe messaging system that is also capable of posting messages to some message queue.
-
Delphi Event-based and Asynchronous Programming eBook complete version released
Dalija Prasnikar replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Relax, it was a joke 🙂 -
Addendum to Martin Fowler quote
Dalija Prasnikar replied to Stefan Glienke's topic in Tips / Blogs / Tutorials / Videos
Somebody needs to make a good compiler first... -
Delphi Event-based and Asynchronous Programming eBook complete version released
Dalija Prasnikar replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Me and my family are fine, now. Thanks! -
Delphi Event-based and Asynchronous Programming eBook complete version released
Dalija Prasnikar replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Not yet, as we have a backlog of other projects that piled up in the meantime. I had COVID and the earthquake hit the region again on December 29. None of this helped my keep my planned schedule. I do plan to release paperback eventually, but can't tell exactly when. -
Delphi Event-based and Asynchronous Programming eBook complete version released
Dalija Prasnikar replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Eh? Imagine how people who pay would feel if I start giving it away Anyway, if this would be bread and you would be hungry, I'd give you a loaf without thinking twice, but it's not. As much as I'd like to think it is, this book is not really something you can't live without, so... Sorry... And about hugs... My husband expressed his wish to have a private chat with you... you'd better lay low for a while -
Delphi Event-based and Asynchronous Programming eBook complete version released
Dalija Prasnikar replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
The full list of code examples from the book Delphi Event-based and Asynchronous Programming is now available on GitHub: https://github.com/dalijap/code-delphi-async -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
I don't know if there is some other reason, but one reason is that with interlocked reference count you can freely use reference counted instances of any type (interfaces, dynamic arrays...) in multithreaded environment for read access if all threads have acquired their strong reference before original reference has been written to (cleared or assigned). In such case you don't need any other more costly locking protection, and you can share same string, so no copying necessary. Clearing such references when they go out of scope is thread safe, because memory deallocation will happen only in case where reference count reached 0. Also getting strong reference from strong reference (variable) held by thread is also thread safe - when I said held by thread it means that no other thread is allowed to write to that variable. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
With this I agree... There is already solution for this bug - triggering reference counting mechanism for const references. Not other gimmick is necessary. I also said why this solution is not viable, because reference counting induces performance penalty. And this is exactly the reason why there is no reference counting trigger for const parameters so that developers have more control over reference counting and to speed up code execution, since in most code passing reference counting instance (regardless of the type) does not require reference counting. No reference counting is speed optimization. Yes, literal string could be initialized to some higher value. But then every time such string would trigger reference counting just like other strings do. But in this case reference counting would be triggered for string literals, and again that would introduce performance penalty for string literals that do not require memory management and reference counting. Comparing some integer value with -1 is inherently faster than increasing/decreasing reference count. Your proposal would again defeat the purpose of having -1 as speed optimization. We already have that. It is called ReferenceCount field in string header. We don't need another number, negative positive or whatever. http://docwiki.embarcadero.com/RADStudio/Sydney/en/Internal_Data_Formats_(Delphi)#Long_String_Types So your idea with negative flag would not work at all, but even if it would that would also require locking operation on reference count field and same performance penalty. It would be simpler to just trigger reference counting instead. Your idea with additional field (if I understood that correctly) would now mean we would have to do locking on two numbers instead of one. Again even more performance penalty. If we want to pay price in performance penalty, then we could just have compiler to omit all speed optimizations and be done with it. And again I think I explained well enough why this will not happen. Not everyone is willing to sacrifice speed because once in a blue moon some developers might shoot themselves in the foot. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Again, -1 is used JUST for string literals. You know when you write s := '123', then '123' is string literal and it is not dynamically allocated and its memory does not have to be managed. That is why there is optimization in RTL JUST for string literals that skips reference counting for them. -1 tells means you are dealing with string literal. You cannot use that value for any dynamically allocated data (strings). -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Only nil pointer does not have any associated data. When you put some address in pointer you have associated it with some data that is not directly stored in variable itself. Since main purpose of pointer types is storing address to something, so if you treat that address as actual value, then you can say that raw pointers are value types. There is some ambiguity here, sure. In case of other reference types, you are definitely not interested in address as value, but content (value) in associated second part and that is what makes strings, interfaces, objects, dynamic arrays reference types. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Pointer is a reference type. But if you are bisecting reference types, then reference part (the immediate value stored in variable) has value type semantics. In other words when you assign one pointer to another you are creating copy of a stored value in that variable alone (reference part), just like when you are assigning one integer to another. If that pointer is not nil - then assigning one pointer to another will still point to the same data location, while pointer itself will have two distinct copies at that time. That also answers the first part of your question. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
It works as expected because TFoo is record and records are value types. That means two things, first there is no additional memory management (heap) involved. s1 holds complete content of record on stack without indirections. Next because size of record does not fit into register and Value is passed as const compiler optimization kicks in and passes reference to s1 and not copy. In other words generated code is the same as it would be if you used var parameter. If you change declaration of TFoo and make it smaller, you would get different result, because Value would now contain independent copy of the data. TFoo = record X: byte; Y: byte; end; If you change declaration of Test to procedure Test(const [ref] Value: TFoo); Then regardless of TFoo size it would be always passed as reference (pointer) to the original data, and you would not have two copies. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
That is because string literals don't require managing memory as they are part of the executable and are stored in data segment. Their reference count of -1 is just flag used for optimization and omitting reference counting that makes no sense for general reference counting mechanism. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
I answered before thinking... so you got me But, real answer is more complicated. Technically, memory representation in Swift allows both variants depending on the size of data (content). So until you discuss actual code, there is not way of telling how will inner representation work. It may be value and it may be reference. In Swift value types and reference types in terms of Swift documentation also means all value types in Swift imply copy on assignment semantic, so for Swift developers that classification carries more weight than actual underlying representation - which again depends on the actual content. Also Swift compiler has(d) bugs around handling "value types" that are not really value types, but rather reference types in terms of Wikipedia definition, that would cause memory leaks under certain conditions (and other issues). I am saying bugs, because some of those I know about were actual bugs, I am not in position to say whether some of those bugs are just "as designed" behavior similar to Delphi const string parameter behavior. I am not that deeply involved with Swift and I am not familiar with all its internals, that also change every five minutes as Swift involves. Just like Delphi strings, Swift "fake" value types can suffer from some problems cause by the fact that they don't occupy single location in memory. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
The only fact there is is that reference counting does not work like that. And it could not work with any bit flipping. Bit flipping does not solve anything. It is not a blasphemy, it is simply not a working solution. Again, I am not against discussing potential solutions to anything, nor how can something be improved, but when your initial understanding is flawed, there are just too many things that I would have to convince you about. -
The Case of Delphi Const String Parameters
Dalija Prasnikar replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
I know. And in Delphi all those types are reference types. In Java all those types are also reference types. Again, definition of value type and reference type does not imply which types in particular language belong to particular category. Value of the string content, not string variable. By your definition all types would be value types. I also quoted Delphi documentation that clearly states value of string variable itself is pointer to actual string data. QED.