The following integer power function returns 0 when the result should be greater than 2^32 if the base argument is unsigned int, but works fine when the base argument type is changed to an unsigned long. Why? Compiler bug?
#include <cstdint>
#include <iostream>
using uint = uint32_t ;
using ulong = uint64_t ;
static constexpr ulong ipow(uint base, uint exp, ulong ans = 1) // Integer power
{
return exp < 1 ? ans : ipow(base*base, exp/2, (exp % 2) ? ans * base : ans) ;
}
int main ()
{
for (int i(2) ; i < 64 ; ++i)
std::cout << "ipow(2," << i << ") = " << ipow(2,i) << "\n" ;
return 0 ;
}
Compiled and ran above code (Apple clang version 17.0.0 (clang-1700.3.19.1)
Target: arm64-apple-darwin24.6.0).
Extract of incorrect output:
ipow(2,27) = 134217728
ipow(2,28) = 268435456
ipow(2,29) = 536870912
ipow(2,30) = 1073741824
ipow(2,31) = 2147483648
ipow(2,32) = 0
ipow(2,33) = 0
ipow(2,34) = 0
ipow(2,35) = 0
base*base, wherebaseisuint, and I suspect that expression could overflow.compiler-bugtag as it is actually not relevant here.