How to fix -Wsubobject-linkage warning?

I get a gcc warning for code that compiles a fine and a warning for free in clang and VC ++, so I assume this is something specific to gcc. This is the code:

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 

and warning:

warning: "myns :: A" has a field "myns :: A :: _ candidates" whose type has no binding [-Wsubobject-linkage]

What does this mean and how to get rid of the warning?

+5
source share
1 answer

I believe that the compiler may be wrong here: the type referenced by the CandidatesCollection must have an external link.

[basic.link] / 4 ... A name with a namespace scope that was not provided by the internal link above has the same relationship as the encompassing namespace if it is a name

...

(4.3) - a named class (section 9) or an unnamed class defined in the typedef declaration, in which the class has the name typedef for binding purposes (7.1.3); ...


[dcl.typedef] / 9 If the typedef declaration defines an unnamed class (or enumeration), the first typedef name declared by the declaration is the class type (or enumeration type) used to indicate the class type (or enumeration type) for binding purposes only (3.5) . [Example:

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

-end example]

Thus, if the CandidatesCollection were defined as

 typedef struct { ... } CandidatesCollection; 

these two passages make it clear that a class called CandidatesCollection will have an external connection.

Then there is

[dcl.typedef] / 2 The typedef name can also be entered using the alias declaration. The identifier following the using keyword becomes typedef-name and the optional qualifier-seq attribute next to the identifier, to this typedef-name. It has the same semantics as if it were introduced by the typedef specifier.

The emphasis is mine. This suggests that the name entered using should give the unnamed class "name for communication purposes" in the same way as the equivalent typedef declaration, thereby ensuring that the class has an external connection.

+1
source

Source: https://habr.com/ru/post/1261338/


All Articles