rabauke / mpl

A C++17 message passing library based on MPI

Home Page:https://rabauke.github.io/mpl/html/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

static constexpr members might not compile without optimization

RaulPPelaez opened this issue · comments

commented

mpl/mpl/cart_comm.hpp

Lines 18 to 25 in c4c83cf

class cart_communicator : public detail::topo_communicator {
public:
enum class periodicity {
periodic, nonperiodic
};
static constexpr periodicity periodic=periodicity::periodic;
static constexpr periodicity nonperiodic=periodicity::nonperiodic;

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 [...]