Given the following code:

===
struct EditorInternalCommand { };

static void createCommandMap()
{
    struct CommandEntry { EditorInternalCommand command; };
}
===

The structure createCommandMap()::CommandEntry is exported from a local-scope
(static) function. When compiling the code above with -fvisibility=hidden, g++
4.3 or 4.4 outputs the following warning:

visibility.cpp:5: warning: 'createCommandMap()::CommandEntry' declared with
greater visibility than the type of its field
'createCommandMap()::CommandEntry::command'

If I add constructors to both structures so that there are symbols emitted, the
ELF symbol table looks like this:
    6: 00000000     22 FUNC    LOCAL  DEFAULT        2
_ZZL16createCommandMapvEN12CommandEntryC1Ev
    7: 00000016     16 FUNC    LOCAL  DEFAULT        2 _ZL16createCommandMapv
   12: 00000000      5 FUNC    WEAK   HIDDEN         6
_ZN21EditorInternalCommandC1Ev

My understanding of the problem is that a "static" function has LOCAL scope but
DEFAULT visibility. The inner structure inherits these properties. However, the
outer structure (EditorInternalCommand) has HIDDEN visibility, which triggers
the warning.

However, since the binding scope is LOCAL, those symbols will not be exported
by the linker in the final ELF object anyways, thereby making them effectively
have hidden visibility.


Workarounds:

Any of the following three actions make the warning disappear:
1) remove the "static" keyword
2) move the inner structure outside the static function
3) place the outer structure in an anonymous namespace

Actions #2 and #3 above change those propeties making both constructors match
either LOCAL/DEFAULT or WEAK/HIDDEN. Action #1 causes the function to become
GLOBAL/HIDDEN, but leaves the inner structure unchanged -- however, the warning
is gone too.


-- 
           Summary: structure inside a static function is exported,
                    producing warning
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: thiago at kde dot org
 GCC build triplet: i586-manbo-linux-gnu
  GCC host triplet: i586-manbo-linux-gnu
GCC target triplet: i586-manbo-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40145

Reply via email to