1

I'm using C++17 and stumbled on a linker error with this kind of code

#include <memory>

struct SomeType
{
    static const int MIN = 0;
    static const int MAX = 0;
};

struct Range
{
    Range(int min=0, int max=0) : min(min), max(max) {}

    int min, max;
};

int main()
{
    auto range = std::make_shared<Range>(
        SomeType::MIN,
        SomeType::MAX
    );
    return 0;
}

On linux using gcc 11.2 this causes linker errors but MSVC builds it without problems (Visual Studio 2019 Version 16.9.2).

undefined reference to `SomeType::MIN'
undefined reference to `SomeType::MAX'

but if I add inline before static const int MIN = 0; and static const int MAX = 0; then it works just fine.

Why does adding the inline fix the linking issue? Why is it a link time issue and not a compile time issue?

Allan Ojala
  • 694
  • 10
  • 22
  • There may be better duplicate targets, but I couldn't find one at first glance. TLDR: you need to either _define_ the static data members outside of your class, or (allowed as of C++17) mark them as `inline` at their in-class declarations. See [P0386R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0386r2.pdf) regarding inline variables: _"A variable declared inline has the same semantics as a function declared inline: **it can be defined, identically, in multiple translation units**"_. – dfrib Sep 20 '21 at 13:29
  • 1
    @dfrib I might be wrong, but I dont think the dupe appllies here. `static` member could be defined in the class already before c++17 when they are `const` and of integral type – 463035818_is_not_an_ai Sep 20 '21 at 13:30
  • 1
    @463035818_is_not_a_number - That's not a definition. Which becomes a problem the moment they are ODR-used. – StoryTeller - Unslander Monica Sep 20 '21 at 13:31
  • You've **declared** `MIN` and `MAX`, but where do you have `const int SomeType::MIN;` and `const int SomeType::MAX;` **defined**? (Assuming you are not using `inline`.) – Eljay Sep 20 '21 at 14:37

0 Answers0