Posts

Static Data Trap. All Tests Passed. But Why is the Output Wrong?

Code coverage is not enough Code coverage is one of those metrics which can easily give you a false sense of security. In real life, code achieving 100% code coverage is often not possible, but that is the least of the problems with using code coverage as a metric of how well-tested some code is. There are some parts of the code and logic that code coverage tools simply cannot cover. Even if you have achieved 100% code coverage for some code, you might still have serious flaws in that code. Every branch is taken, every line is green, all your tests are passing. There is nothing left to do. Right? Wrong? Probably one of the simplest examples that can show this problem is converting a decimal integer number to some other base: const BaseChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; function IntToBase(Value, Base: UInt32): string; begin Result := ''; while Value > 0 do begin Result := (BaseChars[1 + (Value mod Base)]) + Result; Value := Va...

Delphi 13.2 Update

Image
The Delphi 13.2 update has just been released. Ever since the 13.1 update and the new LLVM-based Windows ARM compiler, the LLVM toolchain has entered a cycle of rapid development and improvements. 13.2 continues that trend with a completely revamped 64-bit Linux compiler, which can now be integrated with the 64-bit Delphi IDE. The new Linux compiler is based on LLVM 20, just like the Windows ARMEC compiler, and the debugger format has been upgraded from DWARF v2 to v4, resulting in more complete debug information. The new LLVM toolchain also brings two very important improvements: IR optimizations for better performance of compiled applications, and parallel compiling — parallel code generation — for those two newest LLVM-based compilers: Linux and Windows ARMEC. Of course, turning on code optimization slows down the application building process, but this is where parallel code generation steps in and gives a significant performance boost. Parallel code generation is a configurabl...

With Time, All Software Goes South. AI-Written Software Gets There Faster

There is no better feeling than creating a brand new code repository. For a brief moment, you will have a nice, clean slate without bugs of any sorts, without hacky workarounds, with none of the sauceless spaghetti and half-baked features you never managed to fully write and maintain, but which eventually turn your codebase into a technical debt obstacle course. But that joyous feeling does not last too long. Bit by bit, and sometimes by leaps and bounds, that nice, clean codebase will start to go south, acquiring some, if not all, of the dreadful issues every developer fears. This kind of deterioration is inevitable. No matter what you do, no matter how careful you or your team are, the growing complexity will take its toll. Yes, the more careful and experienced you are, the slower the decline, but anyone claiming they have a perfect codebase is either delusional or has never worked with large-scale systems in production. At some point, small bugs and issues accumulate, the archite...

Excessive Collection Locking

As soon as you step into writing multithreaded code, you will need to work with collections in a thread-safe manner. While Delphi provides some basic thread-safe collections for its own use in the RTL and visual frameworks, those are usually not enough. So you will either end up using some third-party thread-safe collection library, or you will be insipired to roll out your own. Making thread-safe collections is not a very complicated task, but if you are not careful, you can easily end up using locking patterns which will look fine at first glance, but can cause excessive locking when used. You will get thread safety, but running at a snail's pace. Considering that modern computers are powerful enough, such code can still run at an acceptable speed, and you might not even notice that you are burning CPU cycles in vain. Thread-safe Collection To implement any thread-safe collection, you will need a lock. While there are many different lock types we can use based on particular n...

Delphi 13.1 Update: Windows Arm64EC compiler

Image
The Delphi 13.1 update has just been released. One of the most significant new features in this update is the new 64-bit Windows ARM EC compiler. With ARM taking a strong foothold in desktop, laptop, and tablet computers, this is an additional Windows platform which can no longer be ignored. Now, if there is one thing that Microsoft does well, it is compatibility support for existing applications. Which means even your existing 32-bit and 64-bit Intel-based Windows applications will run on the Windows ARM OS. With that in mind, having a Windows ARM compiler at this time may not seem like a mission-critical feature, but this compiler still represents an extremely important milestone in Delphi's evolution. There are several reasons for that. First of all, Delphi developers are primarily Windows developers. Even if we support other platforms, Windows is and will always be our turf. Because Windows ARM EC supports both the VCL and FMX visual frameworks, no matter what kind of Delphi...

Using atomic operations to achieve thread safety

Atomic operations are ones which can be executed on otherwise-unprotected shared data as a single indivisible step, where no other thread will be able to compromise the consistency of either that shared data or the operation itself. In other words, even for operation logic consisting of multiple, compound operations—steps—being atomic means that all those steps will run as an unbreakable whole on the shared data, and multiple threads will not be able to interfere with each other. Most fundamental atomic operations are actually implemented on the hardware level, and rely on specific CPU instructions to ensure atomicity, but some can also be implemented in higher level code with the help of those atomic primitives. Because hardware support is needed for the most fundamental primitives, atomic operations will be limited to simple data types commonly up to a size of a pointer. Support for atomic operations for larger data sizes—double pointers or even more—is hardware-dependent, and Del...

CodeRage 2025: Multi-threaded programming: two problems, you now have

Image
 It is a CodeRage season.  Join me next Tuesday, December 2, at 20:00 GMT for my session "Multi-threaded programming: two problems, you now have" and find out how to avoid some common problems when writing multi-threaded code in Delphi applications. Register now!