One person asking a question will get an answer; two people asking the same question will probably prompt a post. So here’s the latest: MQ listed the XLC/C++ 16 compiler for AIX as deprecated in 2024 and support for it was removed in version 9.4.2. What does that mean for new development or existing applications?
Introduction
The original deprecation notice read:
Support for the XL C/C++ for AIX 16 compiler on AIX is deprecated from IBM MQ 9.3.5. From IBM MQ 9.3.5, you can compile AIX programs using the XLC 17 compiler alongside the XLC 16 compiler.
From the MQ documentation
And then, with 9.4.2 we get:
For Continuous Delivery, the IBM XL C/C++ for AIX 16 compiler is removed from the product at IBM MQ 9.4.2. Compile AIX programs by using the IBM Open XL C/C++ for AIX 17 compiler instead.
The reason this gets special mention is because AIX have decided to switch from their own compiler technology to a system based on the clang compiler. And that has had a number of knock-on effects.
So how does this really affect developers and application programs?
C Applications
For C programs, this should have no effect. Any existing MQ applications will continue to run unchanged. You can build new or rebuild older applications with the new compiler and still run on systems with older versions of MQ installed. There is no requirement to rebuild.
C programs for a given architecture have a well-established ABI (Application Binary Interface). This means that programs and libraries agree on the interfaces between them. The loader/linker processing can ensure that a program compiled with, say, gcc can work with a shared library compiled with an old version of XLC. While the XLC 16 compiler has reached its end-of-life, it is a normal and expected evolution to move to a new version of a C compiler. And if you prefer, even though MQ doesn’t officially list it as supported, you can even use gcc as another alternative compiler.
As always there are constraints about building on one level of the OS and trying to run on an older level (which is not really anything to do with MQ). Switching to the newer compiler will likely need changes to Makefiles. And it might mean you see different error messages. But again that’s not really anything MQ-specific.
C++ Applications
For C++, it’s a very different story.
If you have a C++ program that is using the imq classes to work with MQ, then it will have to be recompiled. If the program is using the C MQI libraries alone, even though it is written in C++ itself, then there should again be no effects – just the same as C programs. ACE, for example, is primarily a C++ program, but it accesses MQ via the C libraries like libmqm. It is not affected by this deprecation/removal.
The C++ issues come about because of the way that C++ handles external symbols such as function names and makes them available to the linker/loader. Each compiler takes a number of aspects of the name and mangles it. Usually there is some combination of a class name, function name, parameters and member types that gets mashed together. This mixture is then turned into a simple flat symbol that can be dealt with when libraries are combined. There is no agreed standard between compilers as to how the flattened name gets generated. It’s even claimed that this lack of standardisation is a good thing.
AIX has, up to now, been very well-behaved with regards to keeping binary compatibility through multiple versions of its C++ compiler. But the move to the clang-based V17 has brought a different name-mangling algorithm. And there is no option to use the original scheme. Some compatibility approaches exist, but they are very limited. See this document for all the V16 to V17 migration details.
The MQ library changes
MQ C++ applications using the imq classes will link against one of the corresponding libraries. For example, libimqs23ia.a. The MQ product build process compiled that library using the V16 name-mangling scheme. But for libimqs23ca.a, the build used the V17 compiler and its scheme. We can see the symbol difference using the nm command. The -C
flag says to print the real name rather than a C++-decoded form. Looking for one randomly-chosen method:
# The C++ name shows in the default nm format $ nm libimqs23ia.a | grep backoutRequeueName ImqQue::backoutRequeueName() D 536881436 12 ImqQue::backoutRequeueName(ImqStr&) D 536881424 12 # The V16 mangled names $ nm -C libimqs23ia.a | grep backoutRequeueName backoutRequeueName__6ImqQueFR6ImqStr D 8204 12 backoutRequeueName__6ImqQueFv D 8216 12 # The V17 equivalent mangled names $ nm -C libimqs23ca.a | grep backoutRequeueName _ZN6ImqQue18backoutRequeueNameER6ImqStr D 536881424 12 _ZN6ImqQue18backoutRequeueNameEv D 536881436 12
We can immediately see different forms for the mangled names. We can also see how methods with the same name but different parameters have different symbols as well.
MQ 9.4.2 does not ship the V16-compatible libraries; the *ia.a
files were removed. Which means that an application that is relying on that version of the name-mangling scheme cannot find the symbols and cannot run. Even tricks with LD_LIBRARY_PATH cannot help unless you have stashed a copy of the old libraries somewhere else. Rebuilding the C++ application against the V17 libraries is the only option.
$ cd /mq_install/mqm.941/usr/mqm/lib64 $ ls libimq* libimqb23ca.a libimqb23ia.a libimqc23ca.a libimqc23ia.a libimqs23ca.a libimqs23ia.a libimqb23ca_r.a libimqb23ia_r.a libimqc23ca_r.a libimqc23ia_r.a libimqs23ca_r.a libimqs23ia_r.a $ cd /mq_install/mqm.942/usr/mqm/lib64 $ ls libimq* libimqb23ca.a libimqb23ca_r.a libimqc23ca.a libimqc23ca_r.a libimqs23ca.a libimqs23ca_r.a
There should be no need to change the application source code as the API itself is not modified. But in your Makefiles, the compiler itself has a new name. And you need to change the library names from *ia.a
to *ca.a
. Possibly other flags to the compiler will be affected.
Other platforms
Although this has hit AIX for the first time, it’s not actually the first occurrence of the issue. Clearly there was no way to use the g++ compiler on that platform as it had yet another mangler.
But at one time on Windows, I think we shipped three different copies of the libraries to deal with various Visual C++ levels. Each of them had a different mangling algorithm. Microsoft eventually realised they had to do something and froze the compiler’s implementation.
The Gnu CC compiler has also gone through multiple ABI/mangling approaches, though I suspect we didn’t even think about that and shipped whichever level of the symbol table came out of the default compiler on the MQ build machines. And at most, one person I’ve heard of has asked about that. The g++
compiler has also apparently settled down relatively recently.
Other symbol table issues
The MQ imq classes have been frozen in function to match the MQI as it was in MQ V6. One of the reasons for that was because the name mangling is not controlled solely by the compiler version. Changing almost any aspect of a class, including adding new public members, can modify the output from the same compiler. MQ V7 had many new API calls and options that would have resulted in lots of changes to the C++ classes. And it could not be done without changing the signatures, breaking existing applications even without changing compilers.
Some of these enforced rebuilding situations could have been a theoretical opportunity to update the imq classes for the newer MQI function. But doing it one platform at a time, when/if that system’s ABI changed, was not really feasible.
Why C++ is an awful choice for API libraries
I made a veiled reference to this in a previous article, but it wasn’t really the best place for details. This seems a much better place.
While C++ may be a perfectly good choice for application programs, I think it is a dreadful choice for API libraries. The variety of compilers and environments make it incredibly hard to support all the options that an application might work with. One product might ship XLC V16-compatible API libraries; another product might ship XLC V17-compatible libraries. Or the package might have been compiled with g++. There is no way an application can work if it needs to use functions from mixed-build libraries.
If you must ship a product where the API library is written in C++, ensure that it really only exposes a C API via extern "C"
. All C++ symbol resolution can then remain inside the API library and not need to go outside. Though that can also mean not using “standard” external class libraries unless they are embedded (statically linked?) into your product library. That is an approach I took for this API exit, which had to use C++, but present a C interface to the calling environment.
This is not a new thing; I remember having similar discussions back when MQ was a baby.
What about providing Open Source libraries?
At least you then have the possibility of recompiling the entire stack. But the build process for C++ applications can be complex. There’s no equivalent of npm install
or go mod
to automatically get the components. One reason, among others, that the MQ C++ libraries were not made Open Source (and we did discuss it) was the cost of needing to create appropriate standalone cross-platform Makefiles or equivalent.
I’ve been looking recently at the OpenTelemetry C++ libraries and their build process is horrible. It requires a bunch of extra tools, making sure you have the right flags. And then making a choice of which ABI version to build for. The entire application stack has to use either their ABI1 or ABI2 variant. Which again makes it really hard to have pre-built instrumented libraries because we can’t know what the application is going to use.
Conclusion
I suspect that this will, in the end, not affect many people. I know that I’ve recommended for many years that C++ apps use the C MQI directly. And given the stabilised function, the imq classes are not particuarly attractive anyway. So I suspect that there are not a lot of active users for it.
But the product documentation and the deprecation notices are perhaps more scary than they need to be.
Hopefully, this has cleared up some of the issues.
This post was last updated on March 10th, 2025 at 09:08 am