I am trying to understand some kind of recursive code for the C ++ code that was passed to me, and I hit some strange behavior. For some reason, the compiler seems to be able to add two values ββat compile time, but left shift execution should be left to run time. And even then the problem arises only if I try to build with C ++ 11 turned on.
The code (which I have welded, and you will see below) defines two pairs of templates - one pair with the name shft and shft_aux and one pair with the name add and add_aux that generate themselves recursively. BTW, the add pattern should not be useful, its sole purpose is to demonstrate the problem, and not generate the actual value of min .
If I compile this code without command line options, it compiles just fine. But if I specify -std=c++11 -stdlib=libc++ , the static_assert in add_aux is still fine, but the static_assert on shft_aux now generates a compile-time error, saying static_assert expression is not an integral constant expression .
Why is the left shift handled differently than adding?
Thank you, Chris
ps I am using clang ++ version Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
#include <climits> template <unsigned size> struct shft; // forward template <unsigned size> struct shft_aux { static const int min = shft<size>::min; }; template <unsigned size> struct shft { typedef shft_aux<size - 1> prev; static const int min = prev::min << CHAR_BIT; }; // Base specialization of shft, puts an end to the recursion. template <> struct shft<1> { static const int min = SCHAR_MIN; }; // ----- template <unsigned size> struct add; // forward template <unsigned size> struct add_aux { static const int min = add<size>::min; }; template <unsigned size> struct add { typedef add_aux<size - 1> prev; static const int min = prev::min + CHAR_BIT; }; // Base specialization of add, puts an end to the recursion. template <> struct add<1> { static const int min = SCHAR_MIN; }; // ----- int main() { static_assert(shft_aux<sizeof(int)>::min < 0, "min is not negative"); static_assert(add_aux<sizeof(int)>::min < 0, "min is not negative"); return 0; }
source share