c++visual-studio-2017c++17compiler-buginline-variable

inline variable is initialized more than once


Im seeing some examples of inline const variable getting initialized (and destructed) 3 times with visual studio 2017. Is this is a bug with the linker ? or is this supposed to happend in some other way ?

linker Comdat folding is set to Off.

Example Code:

#pragma once

struct A {
  A() {
    static int count = 0;
    ++count;
    ASSERT(count == 1);
  }
  ~A() {
  }
};


inline const A a = A();

In my solution, I have the assert fire twice (A constructor called 3 times). Inspecting the call stack shows all call stacks are identical and all calls come from dynamic initializer for a(). Now I know for a fact this class is not used in other parts of the solution since I just created it to investigate this issue.

Im using VS17 15.8.9

Update: Bug report here https://developercommunity.visualstudio.com/content/problem/297876/static-inline-variable-gets-destroyed-multiple-tim.html (you may upvote to help push for the bugfix)


Solution

  • This appears to be an MSVC bug. I'm able to reproduce it with the code below (also with VS2017 15.8.9). Interestingly, I can only reproduce with a Debug build. In Release mode, the optimizer seems to save us.

    Common.h

    #pragma once
    
    #include <iostream>
    
    class Foo
    {
    public:
      Foo()
      {
        std::cout << "Constructing a Foo" << std::endl;
      }
    
      ~Foo()
      {
        std::cout << "Destructing a Foo" << std::endl;
      }
    };
    
    inline Foo const Bar;
    

    other.cpp

    #include "common.h"
    
    void DoOtherStuff()
    {
      std::cout << &Bar << std::endl;
    }
    

    main.cpp

    #include "common.h"
    
    void DoStuff()
    {
      std::cout << &Bar << std::endl;
    }
    
    extern void DoOtherStuff();
    
    int main()
    {
      DoStuff();
      DoOtherStuff();
    }
    

    Output (Debug)

    Constructing a Foo
    Constructing a Foo
    00007FF74FD50170
    00007FF74FD50170
    Destructing a Foo
    Destructing a Foo