I'm using std::make_unique (std::make_shared) to instantiate a class that takes a parameter. This parameter shall be initialized by a static constant.
If this static constant is initialized by a constant initializer (inside class definition) and not defined correctly according requirement from standard (outside class definition) then optimization -O0 shows a linker error but any optimization level (-O2, -O3, -Os) doesn't show any error. The compiled program runs.
I know that the missing static constant definition is an error. Thanks to this question and this question.
Why the linker error shows up only with -O0 if I remove the line "size_t const Foo::bufSize;"? Is this an error within gcc?
I've tested this code with: GCC 5.3.0 for x86 Windows (MinGW) GCC 6.3.0 for x86 Linux (Debian Stretch)
My simplified example code:
#include <iostream>
#include <cstdint>
#include <memory>
class Bar {
public:
Bar(size_t const size)
: barSize(size) { std::cout << "Bar::Bar: Size: " << barSize << std::endl; }
~Bar(void) = default;
private:
size_t barSize;
};
#define USE_CONST_INITIALIZER 1
class Foo {
public:
#if (USE_CONST_INITIALIZER == 1)
static size_t const bufSize = 4096U;
#else
static size_t const bufSize;
#endif
Foo(void)
: spBuffer(std::make_unique<Bar>(Foo::bufSize)) // -Os compiles and links, -O0 shows linker error
//: spBuffer(new Bar(Foo::bufSize)) // no errors, -Os and -O0 compiles and links
{
std::cout << "Foo::Foo: constructed." << std::endl;
}
~Foo(void) = default;
private:
std::unique_ptr<Bar> spBuffer;
};
#if (USE_CONST_INITIALIZER == 1)
size_t const Foo::bufSize; // This definition (btw. required by standard) is essential if compiled with -O0
#else
size_t const Foo::bufSize = 4096U;
#endif
int main(void) {
std::cout << "Hello world!" << std::endl;
Foo foo;
return 0;
}