Hi, It's good hearing from you again, Alexey! On 12/4/19 6:19 PM, Alexey Sheplyakov wrote:
This code relies on integer multiplication overflow to find out the bit size of various integer types. However singed integer overflow is an undefined behavior. Apparently in some contexts GCC uses mod 2^N arithmetics to evaluate the signed integer expressions. As a result `typedef int[2*((T)((T)2 * ... * (T)2) == 0) - 1]` trick works with both signed and unsigned integers (and gives the correct result). Howerver GCC considers an expression involving an integer overflow as a non-constant, and refuses to use it in `static_assert`
Right. According to section 5.19 in the C++11 standard (but the equivalent section 8.20 in C++17 is much more clear), an "integral constant" is implicitly converted to a prvalue where the converted expression is a "core constant". And by the same standard sections it's not a "core constant" if it has undefined behavior like signed integer overflow. I guess that explains why static_assert doesn't work here. But I find it interesting that the C++ requirements on "integral constants" / "core constants" do not seem to apply to the "condition" in typedef int[2*(condition) - 1] trick. I'm unsure if this is really compliant. Anyway, I've applied your patch. All my best, -richy. -- Richard B. Kreckel <https://in.terlu.de/~kreckel/>