visibility attribute in C wrt DSO's

Koenraad Heijlen
Thu Apr 28 16:06:00 GMT 2005

Hey List

I saw some unexpected error messages while compiling some C code with
different versions of GCC. (3.4.x and 4.0.0 Fedora Core 3 blend) 

All these warnings were like this:
$file:$line: warning: `visibility' attribute ignored on non-class types

Now I traced it down to the use of 
__attribute__((visibility("hidden"))) in the declaration of a number of
functions of this form:

return-type * __attribute__((visibility("hidden"))) some_function(args);

I made a simple example, a 'box' library that returns pointers to int's.
The code is pasted at the bottom of this mail, or you could get it at .

The essence is this:

/* in box.h */
HIDDEN int* pb41(void);
int* HIDDEN pb42(void); // Problematic declaration
int* pb43(void) HIDDEN;

I checked the DSO howto from Ulrich Drepper and on page 17, first
example I see that he places the attribute visibility
- behind the variable name of a variable declaration 
- between the return-type and the function name for a function

When I look at the generated .libs/ file with objdump -x I see

000005cb l     F .text  00000025              .hidden pb43
0000173c l     O .data  00000000              .hidden __dso_handle
00000581 l     F .text  00000025              .hidden pb41
00000577 l     F .text  0000000a              .hidden pb33
00000563 l     F .text  0000000a              .hidden pb31
0000056d l     F .text  0000000a              .hidden pb32
000005a6 g     F .text  00000025              pb42

Now I see that 'pb42' is not hidden and all the others are. 

Could any one help me out with the following questions:

1. Why is this code faulty? 
return-type * __attribute__((visibility("hidden"))) some_function(args);

2. What is the correct solution:
HIDDEN type * function
type * function HIDDEN

I guess there's more to it then just the visibility things I see in
objdump so some pointers would be very welcome.

with regards
Koenraad Heijlen

Attached: gcc -v output and my test code.

gcc versions: (gcc -v):
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
disable-checking --with-system-zlib --enable-__cxa_atexit --disable-
libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3)


Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-
checking=release --with-system-zlib --enable-__cxa_atexit --disable-
libunwind-exceptions --with-gxx-include-dir=/usr/include/c++/3.4.3 --
enable-languages=c,c++,f95 --disable-libgcj --host=i386-redhat-linux
Thread model: posix
gcc version 4.0.0 20050406 (Red Hat 4.0.0-0.41.fc3)


Test code:

/* box.c */
#include <stdlib.h>
#include <stdio.h>

#include "box.h"

#define retPTR(n)       int * i; \
                        i = (int *)malloc(sizeof(int)); \
                        *i = n; \
                        return i;

/* some other functions without pointers */
int pb33(void) {

int* pb41(void) {

int* pb42(void) {

int* pb43(void) {

/* EOF */

/* box.h */
#ifndef BOX_H

#define BOX_H

// GCC Extension
#define HIDDEN __attribute__((visibility("hidden")))

int pb33(void) HIDDEN;

HIDDEN int* pb41(void);
int* HIDDEN pb42(void); // Problematic declaration
int* pb43(void) HIDDEN;

#endif /* BOX_H */

/* EOF */

/* poke.c */
#include <stdlib.h>
#include <stdio.h>

#include "box.h"

int main(void) {
        int *i;

        // let's poke the box
        printf("-- Poking the libbox --\n");

        /* Hidden Functions */
        //printf("pb33 : %d\n",pb33());

        /* Hidden Function */
        //i = pb41();
        //printf("pb41 : %d\n",*i);

        /* Not hidden although we meant to hide it */
        i = pb42();
        printf("pb42 : %d\n",*i);

        /* Hidden Function */
        //i = pb43();
        //printf("pb43 : %d\n",*i);


/* EOF */

I compiled all this with a 'Makefile', I'm not sure this is the right
way to do it but I got a .so file of it, corrections are more than

/* Makefile */
# libbox Makefile
CFLAGS= -g -O -Wall

objects = poke.o

all: poke

poke: $(objects)
        libtool --mode=compile $(CC) $(CFLAGS) -c box.c
        libtool --mode=link $(CC) $(CFLAGS) -o box.lo -rpath
        libtool --mode=link $(CC) $(CFLAGS) -o poke poke.o

        @rm -f poke $(objects) box.lo box.o
        @rm -rf .libs

/* EOF */

More information about the Gcc-help mailing list