Discussion:
GCC ignores function attributes
Nikos Chantziaras
2014-06-11 22:36:28 UTC
Permalink
According to the documentation:

https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes

and more specific, the example about the visibility attribute:

void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }

doesn't work for me. I have this C++ function prototype:

const SDL_AudioSpec& __attribute__((visibility("default")))
spec();

Compiling this with g++ 4.8.2 gives me:

warning: 'visibility' attribute ignored on non-class types

I do not understand :-/ I found this bug on GCC's bugzilla:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30361

but it is very old and unconfirmed.

In any event, I have no idea what I am doing wrong here.
Jonathan Wakely
2014-06-12 00:31:13 UTC
Permalink
Post by Nikos Chantziaras
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes
void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
const SDL_AudioSpec& __attribute__((visibility("default")))
spec();
warning: 'visibility' attribute ignored on non-class types
I think the attribute binds to the return type here, which is a
reference (not a class type) so can't be given visibility.

This applies the attribute to the function, not the return type:

const SDL_AudioSpec& spec() __attribute__((visibility("hidden")));
Nikos Chantziaras
2014-06-12 00:42:56 UTC
Permalink
Post by Jonathan Wakely
Post by Nikos Chantziaras
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes
void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
const SDL_AudioSpec& __attribute__((visibility("default")))
spec();
warning: 'visibility' attribute ignored on non-class types
I think the attribute binds to the return type here, which is a
reference (not a class type) so can't be given visibility.
const SDL_AudioSpec& spec() __attribute__((visibility("hidden")));
I've found that this also works:

__attribute__((visibility("hidden"))) const SDL_AudioSpec& spec();

The only one that doesn't, is the documented one :-/ Documentation bug?
Jonathan Wakely
2014-06-12 09:30:15 UTC
Permalink
Post by Nikos Chantziaras
Post by Jonathan Wakely
Post by Nikos Chantziaras
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes
void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
const SDL_AudioSpec& __attribute__((visibility("default")))
spec();
warning: 'visibility' attribute ignored on non-class types
I think the attribute binds to the return type here, which is a
reference (not a class type) so can't be given visibility.
const SDL_AudioSpec& spec() __attribute__((visibility("hidden")));
__attribute__((visibility("hidden"))) const SDL_AudioSpec& spec();
The only one that doesn't, is the documented one :-/ Documentation bug?
No, the example in the documentation is a function with a void return,
and in that case the attribute binds to the function not the return
type. Your function does not have a void return type. I don't know
why that's different, but both the C and C++ compilers treat the
example the same.
Nikos Chantziaras
2014-06-12 16:48:07 UTC
Permalink
Post by Jonathan Wakely
Post by Nikos Chantziaras
Post by Jonathan Wakely
Post by Nikos Chantziaras
https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes
void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
const SDL_AudioSpec& __attribute__((visibility("default")))
spec();
warning: 'visibility' attribute ignored on non-class types
I think the attribute binds to the return type here, which is a
reference (not a class type) so can't be given visibility.
const SDL_AudioSpec& spec() __attribute__((visibility("hidden")));
__attribute__((visibility("hidden"))) const SDL_AudioSpec& spec();
The only one that doesn't, is the documented one :-/ Documentation bug?
No, the example in the documentation is a function with a void return,
and in that case the attribute binds to the function not the return
type.
That can't be. This works:

int __attribute__((visibility("hidden"))) spec();

spec() is indeed hidden, so the attribute is not applied to the return
type at all (if that was even possible; how can you hide a return type.)
Jonathan Wakely
2014-06-12 18:47:23 UTC
Permalink
Post by Nikos Chantziaras
int __attribute__((visibility("hidden"))) spec();
But this isn't hidden:

int* __attribute__((visibility("hidden"))) spec();

because the attribute binds to the return type, which is what the
warning tells you.
Nikos Chantziaras
2014-06-12 21:35:29 UTC
Permalink
Post by Jonathan Wakely
Post by Nikos Chantziaras
int __attribute__((visibility("hidden"))) spec();
int* __attribute__((visibility("hidden"))) spec();
because the attribute binds to the return type, which is what the
warning tells you.
So what's the difference between 'int' and 'int*' here? Why does:

int HIDE spec();

bind to 'spec' but

int* HIDE spec();

doesn't?

Loading...