inline variable is initialized more than once

后端 未结 3 1015
再見小時候
再見小時候 2020-12-18 02:59

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

相关标签:
3条回答
  • 2020-12-18 03:30

    As of today there is an update for visual studio 2017 to version 15.9.24 which fixes the problem.

    From the release notes:

    Fixed C++ compiler bug for proper folding of inline variable dynamic initializers.

    0 讨论(0)
  • 2020-12-18 03:33

    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
    
    0 讨论(0)
  • 2020-12-18 03:50

    I get the bug in both debug and release (/Ox) mode using the MS C++ compiler version 19.16 (comes with, e.g., Visual Studio 15.9.4).

    Inline.Hpp

    #include <iostream>  
    inline struct Foo  
    { Foo() { std::cout << "Constructing a Foo at " << this << std::endl; } }  
    Instance;  
    

    Inline.cpp

    #include "Inline.Hpp"  
    int main() { return 0; }  
    

    Inline2.cpp

    #include "Inline.Hpp"    
    

    After compiling and linking inline.cpp and inline2.cpp, the output on running is:

    Constructing a Foo at 00BE4028  
    Constructing a Foo at 00BE4028  
    

    The compiler and linker correctly resolve the two inline definitions to a single object, but incorrectly call the constructor for each definition, instead of just once. This is a serious bug which renders the "inline variable" feature of C++17 unusable. The "workaround" is to regard inline variables as still unsupported by MS C++ as of version 19.16, even when the /std:c++17 switch is used.

    0 讨论(0)
提交回复
热议问题