This blog post is based on a pre-release version of the RAD Studio software and it has been written with specific permission by Embarcadero. No feature is committed until the product GA release.
Besides the changes to string literals, with support for long and multiline string literals added to the Delphi compiler, there are other relevant changes in the Delphi language coming in 12.0, even if less visible.
One of them is the introduction of the concept of a weak alias data type. A weak alias type is a type with a different name, but acting as an exact replacement of the original type. By contract, a regular alias data type introduces a new data type, which behaves the same as the original one.
The issue in question and the reason this was introduced, is to help developers maintain single source code applications that compile and work the same in 32-bit and 64-bit applications. One of the data types used for code compatibility in this scenario is NativeInt. While the Integer type in Delphi maps to 32-bit numbers invariably, that is regardless of the parget CPU bitness, the NativeInt type adapts to the CPU. It is 32-bit on 32-bit targets (that is, it is an alias of Integer) and it is 64-bit on 64-bit targets (that is, an alias of the Int64 data type). In other words, NativeInt maps to the Pointer type for the given target.
This was true in the past and remains the same in 12.0. The change affects only the type compatibility among these types and how and if you can overload methods based on these types.
In the past, these data types (Integer, NativeInt, and Int64) were treated as distinct, meaning you could write an overloaded function based on them. However, NativeInt was a “strong alias” of Integer or Int64 depending on the platform. This was causing many issues with ambiguous calls, given the compiler couldn’t distinguish the use cases.
Now NativeInt becomes a “weak alias”, which means you cannot use it anymore or a separate type. However, you can use it instead of the two counterparts, not in parallel. In other words, you can no longer overload like this in Delphi:
procedure doIt(I: Integer); overload; procedure doIt(I: Int64); overload; procedure doIt(I: NativeInt); overload;
The third line above will give the compiler an error, as you can see in the image above: it’s a redeclaration. So you must either do this if you want distinct behaviors on how to handle 32-bit vs. 64-bit integers:
procedure doIt(I: Integer); overload; procedure doIt(I: Int64); overload;
Or just write a single version that adapts to the specific platform:
procedure doIt(I: NativeInt); overload;
We know that this change can affect your existing code. It’s important to note that this compromise favored not breaking 32-bit code, but may still require developers to update their code to work for 64-bit.
We have extensively changed several RTL data structures and methods, taking advantage of this change and resolving several open issues but opening up for some incompatibilities. This is a change that is going to help cleaning and maintaining better 32-bit / 64-bit compatibility in the long run, so despite the fact it might affect some existing code - but not very old 32-bit only code we felt it was important for the future of the language.
There is actually more in the Delphi compiler in 12.0, make sure you follow this blog and sign up for the “What’s Coming” event on November 9th to learn more about RAD Studio, Delphi, and C++Builder 12.0.
This blog post is based on a pre-release version of the RAD Studio software and it has been written with specific permission by Embarcadero. No feature is committed until the product GA release.