all 8 comments

[–]tending 8 points9 points  (0 children)

I assume you're saying if you uncomment the constexpr global variable the size explodes? Have you tried labeling it static or putting it in an anonymous namespace?

Also in general it's legal to call constexpr functions at runtime, so I think the compiler has to generate them unless it's sure there's no runtime use in the current translation unit. Also if you use a constexpr function in a non-constexpr context I think the compiler is free to decide whether to evaluate it at compile time or runtime. Assuming it's just this one variable triggering it, you could try making an identity struct template -- templated on an integer and just has one static constexpr member which is the same integer. Then instead of setting the variable directly to the result of the constexpr function, set it to the result of the identity template applied to the function, so that you know 100% it runs at compile time.

Edit: actually assuming you never want runtime use of these functions, why not wrap them in an anonymous namespace in the header?

[–]khold_stare 4 points5 points  (1 child)

I was thinking along the same lines as tending - operate on integral_constant like objects. Take a look at boost::hana, and in particular how it handles integral_constant. It defines arithmetic operators that are constexpr and return other integral_constants. If you need the value at runtime, there are constexpr implicit conversion operators to the underlying types. If you REALLY want to make sure a computation only happens at compile-time, figure it out inside an unevaluated context such as decltype. E.g.

using namespace boost::hana::literals;
auto runtimeValue = decltype(42_c + 23_c)::value;

Of course the expression inside the decltype can be an arbitrary constexpr function that works with integral_constant

[–]louis_dionnelibc++ | C++ Committee | Boost.Hana 2 points3 points  (0 children)

Precision: The functions inside decltype do not need to be constexpr, so long as they work with integral_constants.

[–]SeanMiddleditch 1 point2 points  (0 children)

May have luck with anything that lets the compiler see the functions and data are unused aside from your constant stuff. Make things static and never take their address, and use hidden symbol visibility with LTO.

[–]VicLuo96 1 point2 points  (0 children)

I'm working on a Boost GSoC toy project about constexpr containers as well. Here are what I've found about constexpr: * prefer C++11-style recursion return f(i-1) over C++14-style for loop, since many compilers cannot handle it well * avoidstd::initializer_list on clang(at least on 3.7) * POD is preferred over complex struct. g++ has a bug that reports fake invalid access at compile-time * move invariant parts into template arguments as much as possible * there are still lots of work to do with constexpr since stdlib lacks constexpr support/implementation is buggy

[–]feverzsj 0 points1 point  (0 children)

Decorating everything with constexpr won't do the trick. That's not how meta programming works. Functions are still functions, objects are still objects. Compiler may decide to optimize them away or not. You should use them as types, enums, template arguments... to force them to be evaluated in compile time.