2016-12-15 172 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可能會在這裏出現錯誤的一面。感謝您的澄清。所以,唯一的解決辦法是不使用'看起來好像'。 –