https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84262

            Bug ID: 84262
           Summary: Header file initialization of a static constant causes
                    linker error if code is compiled without optimization
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Serguei.Kolos at cern dot ch
  Target Milestone: ---

I have noticed that my project, which is compiled and linked without errors
using -O2 flag, fails to be linked in 'debug' mode. Below is the minimal code,
which reproduces the problem. 


// BEGIN SAMPLE

#include <vector>

struct D {
    D(unsigned int , unsigned int , unsigned int ) { ; }

};

struct M
{
    static const unsigned int c1 = 1;
    static const unsigned int c2 = 2;
    static const unsigned int c3 = 3;

    M()
    {
        m_data.reserve(1);
        m_data.emplace_back(c1, c2, c3);
    }

    std::vector<D> m_data;
};

int main(int ac, char** av) {

    M m;
}

// END SAMPLE


The code compiles just fine with any level of optimization above zero, e.g.:

> g++ -O1 bug.cc

while removing '-O' flag results in linker error, like:

> g++ bug.cc 
/tmp/user/ccxT4JuS.o: In function `M::M()':
bug.cc:(.text._ZN1MC2Ev[_ZN1MC5Ev]+0x2f): undefined reference to `M::c3'
bug.cc:(.text._ZN1MC2Ev[_ZN1MC5Ev]+0x34): undefined reference to `M::c2'
bug.cc:(.text._ZN1MC2Ev[_ZN1MC5Ev]+0x39): undefined reference to `M::c1'
collect2: error: ld returned 1 exit status



According to the article 9.4.2/4 of the C++ standard the code is probably
missing definitions of the c1, c2 and c3 constants:

"If a static data member is of const integral or const enumeration type, its
declaration in the class definition can specify a constant initializer which
shall be an integral constant expression (5.19). In that case, the member can
appear in integral constant expressions within its scope. The member shall
still be defined in a namespace scope if it is used in the program and the
namespace scope definition shall not contain an initializer."

But what bothers me is the fact that the same (seemingly bogus) code compiles
fine with -OX flag. Is that normal?

Reply via email to