views:

264

answers:

3

I'm getting these two warnings (with GCC 4.2 on MacOSX):

/Users/az/Programmierung/openlierox/build/Xcode/../../src/main.cpp:154:0 /Users/az/Programmierung/openlierox/build/Xcode/../../src/main.cpp:154: warning: 'startMainLockDetector()::MainLockDetector' declared with greater visibility than the type of its field 'startMainLockDetector()::MainLockDetector::<anonymous>'

/Users/az/Programmierung/openlierox/build/Xcode/../../src/main.cpp:154:0 /Users/az/Programmierung/openlierox/build/Xcode/../../src/main.cpp:154: warning: 'startMainLockDetector()::MainLockDetector' declared with greater visibility than its base 'Action'

In this code:

struct Action {
    virtual ~Action() {}
    virtual int handle() = 0;
};


static void startMainLockDetector() {
    /* ... */

    struct MainLockDetector : Action {
         bool wait(Uint32 time) { /* ... */ }
         int handle() { /* ... */ }
    };

    /* ... */
}

I'm not exactly sure what these warnings mean (what visibility?) and how to fix them. (I really want the class MainLockDetector to be local for that function only.)

I have already compiled the same code with a lot of other compilers (clang, GCC 3.*, GCC 4.0, GCC 4.4, etc) and never got any warning for this code.

A: 

It's because you forgot to declare the inheritance as public.

    struct MainLockDetector : public Action {
         bool wait(Uint32 time) { /* ... */ }
         int handle() { /* ... */ }
    };

This causes the "Action" members to be private. But, you've just overridden an Action private member as public (public default in a struct), which could break encapsulation, hence the warning.

DeadMG
This makes no sense to me. As you say yourself "public default in a struct", so the "public" is optional (it's the default for both members and inheritance).
Johannes Schaub - litb
No change, still same warning. Also 'public' doesn't make sense for structs.
Albert
Declaring the inheritance `public` doesn't have any bearing on this problem.
Dominic Cooney
+1  A: 

There seems to be a problem with shared libraries. I assume you are writing a shared library. Look at this explanation. Try to add the command line option -fvisibility-inlines-hidden. The problem seems to be, that gcc tries to export some symbols of MainLockDetector (visible to linking executables and libraries), whereas Action is not exported (invisible to linking executables and libraries). So the visibility of MainLockDetector really is higher than the visibility of Action.

ablaeul
No, it's not a shared library, it's just an application. But why exactly is MainLockDetector exported and Action is not?
Albert
Have you read the linked paper. The interesting part is inside section 2.2.4.
ablaeul
Ok, have read it now (not all but 2.2.4 and a bit more, most of 2.*). Really interesting. But is `-fvisibility-inlines-hidden` related to my problem? Because I have startMainLockDetector not stated as inline explicitely. Also, why exactly doesn't it export Action? As far as I understand the paper, everything should be exported by default, so why not Action?
Albert
I am a bit confused about the visibility stuff. I have formulated a seperate question [here](http://stackoverflow.com/questions/2843796/gcc-visibility-of-symbols-in-standalone-c-applications). Maybe this will also clarify things here.
Albert
Could you also tell us, if the change of the visibility attributes helped at all?
ablaeul
Yes, `-fvisibility-inlines-hidden` doesn't change anything. I just found out that my build environment also sets `-fvisibility=hidden`. So why does that not apply to `MainLockDetector`?
Albert
If `-fvisibility-inlines-hidden` didn't help at all and the other changes in visibility (attributes of pragmas) do not work too, maybe the problem lies somewhere else.
ablaeul
+1  A: 

To fix this problem, try one of below.

  1. Use #pragma GCC visibility push() statement like this.

    #pragma GCC visibility push(hidden)
    struct MainLockDetector : Action {
         bool wait(Uint32 time) { /* ... */ }
         int handle() { /* ... */ }
    };
    #pragma GCC visibility pop
    
  2. Use __attribute__ ((visibility("hidden"))) like this.

    struct __attribute__ ((visibility("hidden"))) MainLockDetector : Action {
         bool wait(Uint32 time) { /* ... */ }
         int handle() { /* ... */ }
    };
    
  3. Add the command line option -fvisibility=default.

For more details, look at http://gcc.gnu.org/wiki/Visibility.

Satachito