[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