0

The following code produces an “undefined reference” error in C++14 mode, and has no issue in c++17 with latest Clang (same for gcc, but works in both cases with VS2017):

#include <memory>

struct S 
{
    static constexpr int i = 42;
};

int main()
{ 
    std::make_unique<int>(S::i); // undefined reference in C++14, no issue in C++17
}

What is changed between two standard revisions related to this issue? Does VS have correct behavior for this code in C++14 according standard?

Adding a definition for S::i fixes the issue for any compiler/standard.

My question is mostly of make_unique behavior, why definition is needed? For instance, I can use std::unique_ptr<int>(new int(S::i)) without definition of S::i.

Also, suggested duplicate doesn’t answer why Visual Studio accepts code in C++14 mode.

αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71
  • 1
    @πάνταῥεῖ my question is mostly of make_unique behavior, why definition is needed? For instance, I can use `std::unique_ptr(new int(S::i))` without definition of `S::i` – αλεχολυτ Apr 05 '19 at 19:20
  • _"my question is mostly of make_unique behavior, why definition is needed?"_ That's kinda kinda completely orthogonal problems. Nothing to do with _implicit inline definition of `static constexpr`_ class members. – πάντα ῥεῖ Apr 05 '19 at 19:24
  • @πάνταῥεῖ it’s not so easy to find the root of the problem while asking until you know the answer. – αλεχολυτ Apr 05 '19 at 19:29
  • 1
    @αλεχολυτ the problem is that `std::unique_ptr` is taking references as parameter, which may make ODR use of the `S::i` variable – Guillaume Racicot Apr 05 '19 at 19:32
  • @αλεχολυτ _"it’s not so easy to find the root of the problem while asking until you know the answer."_ I didn't knew the answer in advance spotting your question. The first thing I noticed was that you mingled up something regarding the necessity of the `static constexpr` definition and `std::unique_ptr`. My reaction was just to lookup a _"c++ static member definition needed before c++17"_ google search. – πάντα ῥεῖ Apr 05 '19 at 19:33
  • @GuillaumeRacicot Do you know how VS is handling this without references? – αλεχολυτ Apr 05 '19 at 19:36
  • @αλεχολυτ it *may* ODR use the varaible. Depends on some factor including inlining, which remove the need of actual references. – Guillaume Racicot Apr 05 '19 at 19:40
  • @GuillaumeRacicot it seems that msvc implicitly define static member even for `const` (i.e. not `constexpr`). Example code succesfully compiled with [msvc](https://rextester.com/HZWKK40469), but failed with [clang](https://rextester.com/UWPHS91086) or [gcc](https://rextester.com/QRHWL48804) on linker stage. – αλεχολυτ Apr 08 '19 at 08:26
  • @αλεχολυτ it's not safe to assume that msvc does that. It may simply inline it or somewhat don't need definition in that case. Taking the `int` by value is sometimes enough. That would be my bet. – Guillaume Racicot Apr 08 '19 at 12:58
  • @GuillaumeRacicot What do you mean by "simply inline"? For c++17 `static constexpr` is implicitly `inline`, and such inlining means definition IIRC (e.g. variable can be ODR-used). BTW taking an address of variable (see my previoud comment) should require to define it, isn't it? – αλεχολυτ Apr 08 '19 at 13:06

0 Answers0