In the following example, I use static_assert to verify that foo is determined at compile time. The static_assert passes and I've checked with an incorrect condition that it's actually active. This implies that foo is known at compile time. But if I step through the code with a debugger, I see that skip_first_word is also executed at run time.
// Skip the first word in p_str
constexpr const char * skip_first_word(const char * p_str) {
return (*p_str == '\0') ? p_str :
(*p_str == ' ') ? p_str + 1 :
skip_first_word(p_str + 1);
}
// constexpr to calculate the length of a string
constexpr size_t str_len(const char * p_str) {
return (*p_str == '\0') ? 0 : str_len(p_str + 1) + 1;
}
int main()
{
constexpr auto foo = skip_first_word("Hello, World!");
constexpr auto foo_size = str_len(foo);
static_assert(foo_size == 6, "Wrong size");
// This assert successfully fails
// static_assert(foo_size == 7, "Wrong size");
// Prevent optimizations
for(auto ptr = foo; *ptr != '\0'; ++ptr) {
volatile auto sink = ptr;
}
volatile auto sink = &foo_size;
return 0;
}
What's going on here? Why can't the foo that was calculated at compile-time be used at runtime?
Edit: This behavior is observed with Visual Studio 2015