2016-12-15 427 views
5

我得到一个gcc警告代码编译罚款和警告免费叮当声和VC + +,所以我认为这是gcc特定的。这是代码:如何解决-Wsubobject-linkage警告?

namespace myns { 
    using TokenList = std::vector<size_t>; 
    using RuleList = std::vector<size_t>; 
    using RulePathPair = std::pair<size_t, TokenList>; 
    using CandidatesCollection = struct { std::map<size_t, TokenList> tokens; std::set<RulePathPair> rules; }; 

    class A { 
    private: 
    CandidatesCollection _candidates; 
    }; 
} // namespace myns 

和警告:

警告: 'myns名字:: A' 有一个字段“myns名字:: A :: _考生,其类型有没有联动[ - Wsubobject-linkage]

这是什么意思和如何摆脱警告?

+2

与您的问题无关,但您为什么使用'using'来为结构定义类型别名?结构名称本身就是类型名称。不是说这是错的,只是它很奇怪。 :) –

+0

对,我在想同样的事情,但我想保持那里的模式。我有一些其他这样的定义,就像这样的表示。 –

+0

它让我想起了旧的C typedef结构模式 – RyanP

回答

1

我相信编译器在这里可能是错误的:CandidatesCollection提到的类型实际上应该有外部链接。

[basic.link]/4 ...尚未给出上述内部键的具有名称命名空间范围具有相同的连锁作为封闭命名空间,如果它是

名称。 ..

(4.3) - 一命名的类(第9节),或者在一个typedef声明,其中所述类具有用于连杆机构的目的typedef名称(7.1.3)所定义的未命名的类; ...


[dcl.typedef]/9如果typedef声明定义的未命名的类(或枚举),由该声明声明为该类类型第一的typedef名(或枚举类型)用于表示仅用于链接目的的类类型(或枚举类型)(3.5)。 [实施例

typedef struct { } *ps, S; // S is the class name for linkage purposes 

末端示例]

因此,如果CandidatesCollection被定义为

typedef struct { ... } CandidatesCollection; 

这两个通道清楚表明由CandidatesCollection命名为类会愉快地拥有外部联系。

再就是

[dcl.typedef]/2的typedef名也可以通过一个别名声明引入。 using关键字后面的标识符将变为typedef-name和可选的属性说明符-seq,其后面的标识符属于typedef-name。它有相同的语义好像它是由typedef说明符引入的。

强调我的。这表明由using引入的名称应该给出未命名的类“用于链接目的的名称”以及相应的声明,从而确保该类具有外部链接。

+0

嗯,有趣的想法。在我看来,clang可能会在这里出现错误的一面。感谢您的澄清。所以,唯一的解决办法是不使用'看起来好像'。 –