[cfe-dev] Question on constexpr
Howard Hinnant
hhinnant at apple.com
Sun Jul 22 17:49:29 PDT 2012
I'm playing with this code created by Scott Schurr and presented at C++Now:
http://cppnow.org/session/cpp11-new-tools-for-class-and-library-authors/
#include <cstddef>
#include <stdexcept>
class str_const
{
const char* const p_;
const std::size_t sz_;
public:
template<std::size_t N>
constexpr str_const(const char(&a)[N]) :
p_(a), sz_(N-1) {}
constexpr char operator[](std::size_t n)
{
return n < sz_ ? p_[n] : throw std::out_of_range("");
}
constexpr std::size_t size() { return sz_; }
};
template <class T = std::size_t>
constexpr
inline
T
binary_const(str_const b, std::size_t n = 0, T x = 0)
{
return n == b.size() ? x :
b[n] == ',' ? binary_const<T>(b, n+1, x) :
b[n] == ' ' ? binary_const<T>(b, n+1, x) :
b[n] == '0' ? binary_const<T>(b, n+1, x*2) :
b[n] == '1' ? binary_const<T>(b, n+1, x*2+1) :
throw std::domain_error("Only '0', '1', ',', and ' ' may be used");
}
int main()
{
constexpr str_const test("Hi Mom!");
static_assert(test.size() == 7, "");
static_assert(test[6] == '!', "");
constexpr unsigned i = binary_const("1111,0000");
return i;
}
$ clang++ -std=c++11 -stdlib=libc++ -O3 test.cpp -S
Everything compiles and runs great (I know, I'm never happy). But when I inspect the assembly of main I see:
callq __Z12binary_constImET_9str_constmS0_
movl $240, %eax
popq %rbp
ret
Now returning 240 is the right answer. But why is binary_const being called at run time? Can't this call be elided because we know it is a constexpr function (without side effects) and that it is going to return the value 240 that we've already computed at compile time?
Howard
More information about the cfe-dev
mailing list