Issue with inline functions in dynamic libraries since GCC 5.1.0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

I ran into an issue since I moved from gcc 4.9.2 (Fedora 21) to gcc
5.1.1 (Fedora 22) when recompiling a piece of code.

The issue is with inline functions in a piece of code that ends up in a
shared library. The linker complains that it cannot find these functions
when declared inline. When declared static inline, everything seems fine.

I wrote some code to isolate the matter:

inline.c:

#include <stdio.h>

#ifndef MY_STATIC
#define MY_STATIC
#endif

MY_STATIC inline int the_inliner(int foo);

int do_main(int val)
{
	int j;
	j = the_inliner(val);
	printf("Result: %d\n", j);
	return j;
}

MY_STATIC inline int the_inliner(int foo)
{
	return foo << 2;
}

(so the difference is whether this function is declared static inline or
just inline.)

user.c:

#include <stdio.h>
extern int do_main(int val);

int main(void)
{
	int i = 100;
	int j;
	j = do_main(i);
	printf("Result 2: %d\n", j);
	return 0;
}

Makefile:

.PHONY: default clean

default: clean user.c inline.c
	gcc --version
	gcc -Wall -Winline -c -Wall -Werror -fpic inline.c -o inline.o
	gcc -Wall -Winline -DMY_STATIC=static -c -Wall -Werror -fpic inline.c
-o inline_s.o
	gcc -Wall -Winline -shared -o libinline.so inline.o
	gcc -Wall -Winline -shared -o libinline_s.so inline_s.o
	-gcc -Wall -Winline user.c -o user -L. -linline
	gcc -Wall -Winline user.c -o user_s -L. -linline_s
	-LD_LIBRARY_PATH=. ./user
	LD_LIBRARY_PATH=. ./user_s
	ls -l

clean:
	rm -f *.o *.so user user_s

On gcc 4.8.2 on Fedora 21, this gives the expected result:

$ make
gcc --version
gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gcc -Wall -Winline -c -Wall -Werror -fpic inline.c -o inline.o
gcc -Wall -Winline -DMY_STATIC=static -c -Wall -Werror -fpic inline.c -o
inline_s.o
gcc -Wall -Winline -shared -o libinline.so inline.o
gcc -Wall -Winline -shared -o libinline_s.so inline_s.o
gcc -Wall -Winline user.c -o user -L. -linline
gcc -Wall -Winline user.c -o user_s -L. -linline_s
LD_LIBRARY_PATH=. ./user
Result: 400
Result 2: 400
LD_LIBRARY_PATH=. ./user_s
Result: 400
Result 2: 400
ls -l
total 60
-rwxrwx---. 1 root vboxsf  276 Jun 26 23:35 inline.c
-rwxrwx---. 1 root vboxsf 1736 Jun 27 00:30 inline.o
-rwxrwx---. 1 root vboxsf 1688 Jun 27 00:30 inline_s.o
-rwxrwx---. 1 root vboxsf 8093 Jun 27 00:30 libinline.so
-rwxrwx---. 1 root vboxsf 8044 Jun 27 00:30 libinline_s.so
-rwxrwx---. 1 root vboxsf  662 Jun 27 00:08 Makefile
-rwxrwx---. 1 root vboxsf 8544 Jun 27 00:30 user
-rwxrwx---. 1 root vboxsf  156 Jun 26 23:34 user.c
-rwxrwx---. 1 root vboxsf 8544 Jun 27 00:30 user_s


On gcc 5.1.1 on Fedora 22, it fails when the inline function is not
declared static:

$ make
rm -f *.o *.so user user_s
gcc --version
gcc (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gcc -Wall -Winline -c -Wall -Werror -fpic inline.c -o inline.o
gcc -Wall -Winline -DMY_STATIC=static -c -Wall -Werror -fpic inline.c -o
inline_s.o
gcc -Wall -Winline -shared -o libinline.so inline.o
gcc -Wall -Winline -shared -o libinline_s.so inline_s.o
gcc -Wall -Winline user.c -o user -L. -linline
./libinline.so: undefined reference to `the_inliner'
collect2: error: ld returned 1 exit status
Makefile:13: recipe for target 'default' failed
make: [default] Error 1 (ignored)
gcc -Wall -Winline user.c -o user_s -L. -linline_s
LD_LIBRARY_PATH=. ./user
/bin/sh: ./user: No such file or directory
Makefile:13: recipe for target 'default' failed
make: [default] Error 127 (ignored)
LD_LIBRARY_PATH=. ./user_s
Result: 400
Result 2: 400
ls -l
total 48
-rw-rw-r--. 1 bmevisse bmevisse  276 Jun 26 23:35 inline.c
-rw-rw-r--. 1 bmevisse bmevisse 1640 Jun 27 00:32 inline.o
-rw-rw-r--. 1 bmevisse bmevisse 1688 Jun 27 00:32 inline_s.o
-rwxrwxr-x. 1 bmevisse bmevisse 8056 Jun 27 00:32 libinline.so
-rwxrwxr-x. 1 bmevisse bmevisse 8048 Jun 27 00:32 libinline_s.so
-rwxrwx---. 1 bmevisse bmevisse  662 Jun 27 00:08 Makefile
-rw-rw-r--. 1 bmevisse bmevisse  156 Jun 26 23:34 user.c
-rwxrwxr-x. 1 bmevisse bmevisse 8592 Jun 27 00:32 user_s

>From the documentation at
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Inline.html#Inline I cannot
make up why this doesn't work with gcc 5.1.1. This section of the manual
is 100% the same as for gcc 4.9.3.

Can someone please explain this to me?

Thanks,

Bas.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux