[cfe-dev] Question on constexpr

Fernando Pelliccioni fpelliccioni at gmail.com
Tue Jul 24 15:50:27 PDT 2012


On Tue, Jul 24, 2012 at 7:23 PM, Howard Hinnant <hhinnant at apple.com> wrote:

> On Jul 24, 2012, at 6:05 PM, Fernando Pelliccioni <fpelliccioni at gmail.com>
> wrote:
>
> >
> >
> > On Sun, Jul 22, 2012 at 9:49 PM, Howard Hinnant <hhinnant at apple.com>
> wrote:
> > 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
> >
> > _______________________________________________
> > cfe-dev mailing list
> > cfe-dev at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> >
> >
> >
> > Hello Howard,
> >
> > What is the purpose of throwing an exception in a constexpr function?
> > Or rather... What are the implications of throwing in a constexpr
> function?
>
> If you supply a non-constexpr argument that would cause the exception to
> be thrown, or if you assign the result to a non-constexpr object, then you
> will get the run time exception.
>
> If you are using the function to initialize a constxpr object, then you
> must be supplying constexpr arguments as well.
> And if you supply a constexpr argument that would cause the exception to
> be thrown (if the function were to be executed at run time), then you will
> get a compile-time failure along the lines of:
>
> test.cpp:183:24: error: constexpr variable 'i' must be initialized by a
> constant expression
>     constexpr unsigned i = binary_const("11*11,0000");
>                        ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~
> test.cpp:175:12: note: subexpression not valid in a constant expression
>            throw std::domain_error("Only '0', '1', ',', and ' ' may be
> used");
>            ^
> test.cpp:174:26: note: in call to 'binary_const({&"11*11,0000"[0], 10}, 2,
> 3)'
>            b[n] == '1' ? binary_const<T>(b, n+1, x*2+1) :
>                          ^
> test.cpp:174:26: note: in call to 'binary_const({&"11*11,0000"[0], 10}, 1,
> 1)'
> test.cpp:183:28: note: in call to 'binary_const({&"11*11,0000"[0], 10}, 0,
> 0)'
>     constexpr unsigned i = binary_const("11*11,0000");
>                            ^
> 1 error generated.
>
> So the purpose is for error checking, which will happen either at run
> time, or at compile time, depending on how the function is used.
>
> Howard
>
>

Howard, thank you very much for your explanation.
I thought that "throw" was the culprit.

Regards,
Fernando.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120724/07d32d67/attachment.html>


More information about the cfe-dev mailing list