In November, we released C++Builder 10.3.0 with an updated Clang-enhanced C++ compiler. This compiler:
- Was C++17 compliant
- Had an updated Dinkumware STL
- Was better at optimizing code, produced faster executables, and more
Overall, a significantly worthwhile upgrade. You can read more about what was new for C++ in 10.3.0 here.
The updated compiler was only available for a 32-bit Windows target. However, if you’re building for Windows you likely want to be able to target both Win32 and Win64, or possibly even Win64 only. I’m pleased to say, we now have that available!
In 10.3.2, we now have the updated compiler available for Win64 as well, meaning you can use the latest toolchain and latest C++ standard for all Windows targets.
In the above screenshot, you can see a project group demonstrating many C++17 language features. I’ve added the Win64 target, and each app runs.
The benefits of the new updated Clang compiler compared to the one in 10.2.x, and to the classic compiler, are:
- Use up to date, current code
- Make use of popular third party C++ libraries (several of which are on GetIt)
- Take advantage of better optimisations and performance
There are some great features in C++14 and C++17 you can now use. There are some great overviews of C++17, including:
- This github document by Tony Van Eerd lists all features, with examples. It’s a great read
- This very detailed blog post by Bartłomiej Filipek also examines everything new in C++17
Because we are moving straight from C++11 to C++17, we also now support C++14:
- This Dr Dobb’s article has a good overview, with code, of new items in C++14
- This github document by Anthony Calandra has info about what’s new in all modern C++ versions, C++11 onwards
Now, as of 10.3.2, you can use this for all Windows targets, both Win32 and Win64.
Intrinsics and builtins
In 10.3.2 we have also focused on the intrinsics and built-ins the compiler can provide in the Clang-enchanced toolchain.
An intrinsic is a function that is provided by the compiler, not by source code. By this definition, there’s really no particular difference between an intrinsic and a builtin, just different terms for the same thing. Below, they are categorised as functions used in Windows header files (often macros that are fulfilled via a compiler builtin), vs other compiler-provided functions. Typically the compiler-provided ones can vary by toolchain, but the ones used in winnt.h you would expect to be provided on any compiler targeting the Windows platform.
These kind of improvements are part of ensuring that the Clang toolchain is an easy upgrade from the classic toolchain, and also that it’s easy to use third-party C++ libraries in C++Builder.
Windows Intrinsics
In the past, you could sometimes run into errors with intrinsics like InterlockedCompareExchangePointer, declared in winnt.h.
The vast majority of Interlocked* and similar functions are now available in 10.3.2.
Compiler Builtins
The Clang-enhanced compilers provide other intrinsic or builtin functions, including those used by other compiler toolchains like gcc. There are a couple of hundred, although only ten are required for the top 30% of open source code using builtins. There’s a good introduction to the Clang intrinsics here.
Here is some sample dummy code that demonstrates the ten most commonly used builtins. Both the iOS/Android and Windows compilers will build this:
void common(); void rare(); #if !defined(EXPRESSION) #define EXPRESSION 0 #endif static const int table[] = { __builtin_constant_p (EXPRESSION) ? (EXPRESSION) : -1, }; int test(int x, unsigned short us, volatile unsigned u, long long ll) { if (__builtin_expect(x, 0)) { common(); } else { rare(); } x = __builtin_bswap32(x); int i = __builtin_clz(x); i += __builtin_clz(x); i += __builtin_bswap16(us); i += __builtin_bswap64(ll); __sync_fetch_and_add(&x, 1); __sync_synchronize(); __sync_fetch_and_add(&u, 1); return u + i; }
You may not use these often in your own code, but they are useful; they may certainly be used by libraries you rely on.
Upgrading
The compiler can understand C++14, 11, and 98/03 (as C++17 is with some small exceptions, a superset of features.) If you are already using the Clang-enhanced compiler this should be very smooth – or outright unnoticeable – simply that you can now use the new features and get faster compiled code.
If you use the classic compiler, we’re steadily working on removing barriers to upgrading. For example, for a while many of the reasons customers communicated to us were about the RTL, such as missing methods. Those were resolved in 10.3 (naturally with even more improvements in 10.3.2, such as the intrinsics and builtins available in 10.3.2, see above) and we see many people finding it very easy to move their code over to Clang (toggle the switch, rebuild, fix occasional syntactical issues because Clang is a stricter compiler, but that’s it. In terms of language, it’s a straightforward task.)
We have some other items planned to improve other areas. We do recommend upgrading to the Clang toolchain, because it is the future, and at some point we will deprecate the classic compiler. Even if you don’t use it every day, I would suggest you use 10.3.2’s toolchain to build and ensure your code is compatible, ie plan for this upcoming switch. You may find that some of 10.3.2’s features, like improved async code completion, or the performance of compiled code (twice as fast as with classic!) are so worthwhile you switch over completely.
Debugging with Optimized Code
In the past, when you enabled debug info, the compiler would automatically fall back to optimisation level 0. This is often important when debugging, because when you have optimisations enabled you often cannot place breakpoints, see some variables, etc due to various compiler optimisations. However, this was not optional. Despite having an optimisation level set, if told to generate debug info, the compiler always used optimisation level 0.
This is now changed. If you have an optimisation level set and you also generate debug info, both settings will be respected. This allows you to debug the actual optimised code you may want to release with — noting that debugging with optimisations can be problematic, because code is optimised away or otherwise made unavailable to be inspected by the debugger. We made some changes in this area in 10.3.0, but this is now always the case, including Win64.
If you see changes in debugging after upgrading to 10.3.2, double-check your project options to make sure your Debug target is specifically set to no optimisations.
Overview
In 10.3.2, we have a great updated compiler that speaks the latest C++ standard, C++17. It lets you use modern language features in your own code, but also pull in useful third party libraries, plus has additional benefits such as better optimisation. You can use this to target Win32 and Win64, ie all of Windows, and if you had been waiting because Win32 alone was not enough, this is the release to get!
If you have an active update subscription, you can download it now:
You can read more about what’s new here, and if you want detailed information, we will be posting blogs over the next few days. We also have a free webinar on Wednesday July 24th where we’ll cover what’s new, give some demos, and have a live Q&A. You can join that webinar here!