visibility attribute in C wrt DSO's
Koenraad Heijlen
koenraad@heijlen.be
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
http://koenraad.heijlen.be/rnd/c/attrib_vis_box.tgz .
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
declaration
When I look at the generated .libs/libbox.so file with objdump -x I see
this:
...
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
or
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)
and
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) {
ret(500)
}
int* pb41(void) {
retPTR(600)
}
int* pb42(void) {
retPTR(700)
}
int* pb43(void) {
retPTR(800)
}
/* 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);
exit(0);
}
/* 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
welcome.
/* Makefile */
# libbox Makefile
CFLAGS= -g -O -Wall
CC=gcc
objects = poke.o
all: poke
poke: $(objects)
libtool --mode=compile $(CC) $(CFLAGS) -c box.c
libtool --mode=link $(CC) $(CFLAGS) -o libbox.la box.lo -rpath
`pwd`
libtool --mode=link $(CC) $(CFLAGS) -o poke poke.o libbox.la
clean:
@rm -f poke $(objects) box.lo box.o libbox.la
@rm -rf .libs
/* EOF */
More information about the Gcc-help
mailing list