1

The following only links successfully with -std=c++17 or above. -std=c++14 or below gives an unresolved external error:

In function `C::f()':
C.cpp:(.text+0x19): undefined reference to `C::kConstant' 

Why doesn't this work with the c++14 standard and does work with the c++17 standard? (tested with both GCC and Clang)

And why does the commented-out workaround work even on c++14?

C.h

#pragma once

class C {
public:
    static constexpr int kConstant = 10;
    int f();
};

C.cpp

#include "C.h"

#include <algorithm>

int C::f()
{
    // This only works with -std=c++17 or above
    return std::min (1, kConstant); 

    // This works even with -std=c++14
//    return std::min (1, static_cast<int> (kConstant));
}

Main.cpp

#include "C.h"

int main()
{
    C c;
    c.f();
}

Wandbox

Update: This question isn't an exact duplicate, but has an answer which answers most of my question. It doesn't answer why the workaround works with -std=c++14, though, and the original doesn't. Is it perhaps because in the original the variable is odr-used, and in the workaround it is not?

Danra
  • 9,546
  • 5
  • 59
  • 117
  • The question isn't an exact duplicate, though the answer there answers most of my question. (It doesn't answer why the commented-out workaround works even with `-std=c++14`) – Danra Jan 30 '19 at 11:55
  • 2
    The commented workaround creates an `int` prvalue. The const reference `std::min` expects thus doesn't try to bind to `kConstant` (and odr use it due to it). I edited in another duplicate that addresses it (which also has an answer mentioning a cast). – StoryTeller - Unslander Monica Jan 30 '19 at 12:35
  • @StoryTeller Awesome, thank you! – Danra Jan 30 '19 at 12:49
  • @StoryTeller By the way - isn't it an issue (in both compilers) that I do not get a warning in `-std=c++14` due to trying to initialize the non-inline static constexpr member in its declaration, which should have no effect, rather than in its (missing) definition? – Danra Feb 03 '19 at 10:20
  • 2
    The declaration must contain an initializer. So there is no problem. That's what facilitates using it as a constexpr, so long as it isn't odr-used. – StoryTeller - Unslander Monica Feb 03 '19 at 10:24
  • @StoryTeller Of course. Thanks! – Danra Feb 03 '19 at 11:56

0 Answers0