提问者:小点点

G++根据优化设置不链接


所以,这两天都在折磨着我:

我无法链接我的应用程序,这取决于我使用的编译器和使用的优化级别:

  • gcc-O1-O2-O3上运行良好,但在-O0
  • 上失败
  • clang-o2-o3时运行良好,在-o1-o0时失败。

有一堆可怕的模板在里面,但我看不出这种模糊的行为有什么理由。

下面是再现问题的最少量代码:

#include <map>
#include <memory>
#include <iostream>

using id_type = long;

class CB : public std::enable_shared_from_this<CB>
{
public:
    CB() = default;
    virtual ~CB() = default;
};

template<class F, class C> class SC : public CB
{
};

class FB
{
public:
    virtual ~FB() = default;
    template<class T, class B> T* as(B* v) const { return dynamic_cast<T*>(v);}
};

template<class T>
class F : public FB
{
public:
    virtual std::shared_ptr<CB> create() const
    {
        auto n = std::make_shared<T>();
        return n;
    }
};

struct  B
{
    virtual ~B() = default;
    static const id_type ID = 1;
};

class A : virtual public B, virtual public SC<A, B>
{
public:
    A() = default;
};

static std::map<id_type, std::shared_ptr<FB>> crtrs {
        {A::ID, std::make_shared<F<A>>()}
    };

int main()
{
    std::cout << crtrs.size();
}

这里有相同的在线https://gcc.godbolt.org/z/sb9b5e

下面是错误消息:

fld@flap ~/work/p/test1                                                                                                                                                                                                                                                           
> $ g++ -O1 main.cpp                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                          
> $ g++ -O2 main.cpp                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                         
> $ g++ -O3 main.cpp                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                           
> $ g++ -O4 main.cpp                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                            
> $ g++ -O0 main.cpp                                                                                                                                                                                                                                                                        
/tmp/cc8D7sNK.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x1c0): undefined reference to `B::ID'
collect2: error: ld returned 1 exit status
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                            
> $ clang++ -O0 main.cpp                                                                                                                                                                                                                                                                    
/tmp/main-c49b32.o: In function `__cxx_global_var_init.1':
main.cpp:(.text.startup+0x7a): undefined reference to `B::ID'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                           
> $ clang++ -O1 main.cpp                                                                                                                                                                                                                                                                    
/tmp/main-cf18ee.o: In function `__cxx_global_var_init.1':
main.cpp:(.text.startup+0x3c): undefined reference to `B::ID'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                            
> $ clang++ -O2 main.cpp                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                             
fld@flap ~/work/p/test1                                                                                                                                                                                                                                                           
> $ clang++ -O3 main.cpp                                                                                                                                                                                                                                                                    
                                                                                     

如果有人有任何想法可能是什么原因,任何提示都是非常欢迎的。


共1个答案

匿名用户

您没有在任何地方提供B::ID的定义。 只是由于优化程度较高,编译器会忽略所有的访问。

您需要在顶层范围添加静态成员的定义:

const id_type B::ID;

另见:https://en.cppreference.com/W/cpp/language/static

如果您使用的是C++17或更高版本,您也可以使b:idconstexpr而不是const,那么您就不需要单独的定义了。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(g++|优化|设置|链接)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?