static constexpr members might not compile without optimization
RaulPPelaez opened this issue · comments
Lines 18 to 25 in c4c83cf
Compiling a source using "periodic" or "nonperiodic" will not compile with -O0 in some compilers.
For example this code:
#include<mpl/mpl.hpp>
int main(){
const mpl::communicator & comm_world(mpl::environment::comm_world());
mpl::cart_communicator::sizes dims({{0, mpl::cart_communicator::periodic}});
auto comm = mpl::cart_communicator(comm_world, mpl::dims_create(comm_world.size(), dims), true);
return 0;
}
Fails to compile with g++ 4.8 -O0 with the error:
/tmp/ccEc4I5T.o: In function `main':
mpl_error.cpp:(.text+0x2c): undefined reference to `mpl::cart_communicator::periodic'
This happens because C++11 does not guarantee that static constexpr members are implicitly inlined, although they end up inlined with optimizations. In fact the standard requires to define the members outside according to this ( https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char/ ).
This can be solved by compiling with optimizations or explicitly defining the members outside the class by adding the following line after the declaration of cart_comunicator:
constexpr cart_communicator::periodicity cart_communicator::periodic;
Of course this is not restricted to this class.
On the other hand g++ 5.5 is more permissive and compiles without issue even with -O0.
I think, this is a bug of the GCC 4.8 compiler. See https://en.cppreference.com/w/cpp/language/static .
If a static data member of LiteralType is declared constexpr, it must be initialized with an initializer in which every expression is a constant expression [...]