On 25/01/2021 23:08, Gavin Lambert via Boost wrote:
On 26/01/2021 10:53 am, Edward Diener wrote:
Please name the Boost low level libraries which have specific code aimed at the platform/architecture combination. I am not talking about code for just Mac or Linux or Solaris or Windows but code that actually does something different when run on Intel or ARM or AArch64 etc. I still imagine that if such Boost libraries exist there are still very, very few Boost libraries with dependence on such code. I am not arguing that testing on non-Intel is in any way wrong but simply that very, very few libraries should be impacted by different architectures in any way.
Boost.Atomic (and consequently Boost.Lockfree too) is the obvious one (that Niall already hinted at), but parts of Boost.Thread also apply.
Add to that list other low-level libraries such as Boost.Endian, Boost.Coroutine[2], and Boost.Fiber as well.
There are also some surprise gotchas in other libraries that do their own spinlocks or pointer-packing, such as Boost.SmartPtr and likely others.
Meanwhile other libraries like Boost.Serialization (and consumers of same) also make their own assumptions about things like endianness and type structure, which may not matter too much in isolation but becomes very important if you're intending to use it as a portable network or disk format.
There are even more subtle problems than that. Consider this bit of code I encountered recently. This was a trivially copyable struct whose contents were initialised at construction to all bits one by as if memset(this, 0xff, sizeof(T)). The struct's members were set, or not set, by code depending on what happens at runtime. If a member was set by code, its value would not be all bits one. The logical code to write therefore was this: // All bits one representation is a negative NaN under IEEE 754 static constexpr float FLOAT_UNSET = -__builtin_nanf("0xffffff"); struct Foo { float x{FLOAT_UNSET}; constexpr Foo() {} // this is constexpr }; ... if(foo.x == FLOAT_UNSET) ... The above code works absolutely fine if, and only if your compiler is x86/x64/ARMv8 and the target is x86/x64/ARMv8. If your compiler, OR your target, is ARMv7, all bets are off. Why? Because ARMv7 doesn't fully implement NaN. So, if the compiler were x64/ARMv8 and the target were ARMv7, IF the compiler executes the code consteval, you get all bits one float, but if instead it executes the code at runtime, you get some other NaN float. This is because consteval executed expressions by definition are what the compiler itself experiences, which may be quite different to what the target architecture experiences. Subtle stuff like the above causes all sorts of fun in the real world. x64 is extremely benign and tolerant compared to ARMv7, which is probably bigger in terms of total code execution space nowadays. So, restating what I said earlier, I think good engineering means you ensure your C++ works well on ARMv7, and if it works well there, you have an excellent chance of it working well on x64 and ARMv8. The reverse is not true. And incidentally ARMv7 will be a huge chunk of market share for decades to come. Most of the mid low end microcontrollers are ARMv7, they likely will continue to displace PIC and AVR CPUs. Those didn't run C++ well, so we never really experienced much of our userbase trying to say run Boost on them. However all ARMv7 CPUs run C++ very well, so it would be a great surprise if more copies of Boost don't start getting shipped on billions of lower end embedded systems in the coming decade. Niall