https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71827
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- __INTPTR_TYPE__ foo () { m: n: constexpr __INTPTR_TYPE__ a = ((__INTPTR_TYPE__) &&n - (__INTPTR_TYPE__) &&m) + 23; return a; } compiles fine, so it is considered an integral constant expression that just doesn't fold into an INTEGER_CST. For the template parameter we need an INTEGER_CST (I bet in various other cases). constexpr int foo (const int *a) { m: n: constexpr __INTPTR_TYPE__ b = ((__INTPTR_TYPE__) &&n - (__INTPTR_TYPE__) &&m) + 23; return a[b]; } const int c[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; constexpr int d = foo (c); is rejected though: pr71827-4.C:9:23: in constexpr expansion of ‘foo(((const int*)(& c)))’ pr71827-4.C:5:13: error: ‘(((long unsigned int)((((long int)(&& n)) - ((long int)(&& m))) + 23)) * 4)’ is not a constant expression return a[b]; ^ clang++ rejects all of these. So perhaps replace the assert with an error message if the expression is not INTEGER_CST?