https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80265
--- Comment #9 from Pedro Alves <palves at redhat dot com> --- FWIW, I've tried to poke a bit more at this, to try to make it _not_ work, but couldn't. It seems to always do what we need. These all work/compile too: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ constexpr int constexpr_strcmp(const char *s1, const char *s2) { while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s1 < *s2) return -1; else if (*s1 > *s2) return 1; return 0; } constexpr int my_strcmp(const char *s1, const char *s2) { if (__builtin_constant_p (s1[0]) && __builtin_constant_p (s2[0])) return constexpr_strcmp (s1, s2); return strcmp (s1, s2); } constexpr bool str4() { char s[4]= {}; int i = 0; for (; i < 3; i++) s[i] = i + 1; return ce_char_traits<char>::length(s) == 3; } static_assert( str4() ); constexpr int foo (char x, char y) { char a[10] = "abcde"; a[2] = x; a[4] = y; return ce_char_traits<char>::length(a); } static_assert (foo ('1', '2') == 5); static_assert (foo ('1', '\0') == 4); bool runtime() { char s[] = "str"; s[0] = 'l'; s[1] = '\0'; return ce_char_traits<char>::length(s) == 1; } bool runtime2() { char s[4]= {}; int i = 0; for (; i < 3; i++) s[i] = i + 1; return ce_char_traits<char>::length(s) == 3; } bool runtime3() { constexpr char s[] = "str"; return ce_char_traits<char>::length(s) == 1; } int main () { assert (runtime ()); assert (runtime2 ()); assert (runtime3 ()); } static_assert (my_strcmp("hello", "hello") == 0); static_assert (my_strcmp("hello", "hell2") > 0); static_assert (my_strcmp("hell2", "hello") < 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ And I confirmed that "constexpr_strlen" / "constexpr_strcmp" are NOT emitted / called as runtime functions, both at -O0 and -O2.