Re: Port from Win to OSX with Inline functions
Re: Port from Win to OSX with Inline functions
- Subject: Re: Port from Win to OSX with Inline functions
- From: Chris Edgington <email@hidden>
- Date: Tue, 10 Oct 2006 10:29:23 -0400
2) By default - an inlined function will also have a regular non-
inlined copy in the object file.
So - the short-term answer is to redefine __INLINE as "extern
inline __attribute((always_inline))" and to build with
optimizations enabled. Ultimately, however, I will likely need to
change the prorotypes and function definitions to be static - so
they work whether or not they are inlined.
Actually, the only thing inline means is that it's OK if there are
multiple definitions of a function and the linker shouldn't complain.
I thought "inline" was a compiler issue - not a linker issue?
I believe is that your problem is that your prototypes aren't
inline -- you MUST fix at least that -- otherwise, the non-inlined
prototype will take precidence over the
inline definition.
Definitely the prototype is inline. Here is the sample I created:
------
macbook:~/dev/inline chris$ cat macinline1.c
#include <stdio.h>
#define INLINER inline
INLINER void macfn1(void);
INLINER void macfn1(void)
{
printf("macfn1-1-->\n");
return;
}
void macfn2(void)
{
printf("macfn2-->\n");
macfn1();
return;
}
------
Here is the assembly code produced by the compiler with optimization
turned on:
------
macbook:~/dev/inline chris$ cat macinline1.s
.cstring
LC0:
.ascii "macfn1-1-->\0"
.text
.globl _macfn1
_macfn1:
pushl ëp
movl %esp, ëp
pushl ëx
subl $20, %esp
call ___i686.get_pc_thunk.bx
"L00000000001$pb":
leal LC0-"L00000000001$pb"(ëx), êx
movl êx, (%esp)
call L_puts$stub
addl $20, %esp
popl ëx
popl ëp
ret
.cstring
LC1:
.ascii "macfn2-->\0"
.text
.globl _macfn2
_macfn2:
pushl ëp
movl %esp, ëp
pushl ëx
subl $20, %esp
call ___i686.get_pc_thunk.bx
"L00000000002$pb":
leal LC1-"L00000000002$pb"(ëx), êx
movl êx, (%esp)
call L_puts$stub
leal LC0-"L00000000002$pb"(ëx), êx
movl êx, (%esp)
call L_puts$stub
addl $20, %esp
popl ëx
popl ëp
ret
.section
__IMPORT,__jump_table,symbol_stubs,self_modifying_code
+pure_instructions,5
L_puts$stub:
.indirect_symbol _puts
hlt ; hlt ; hlt ; hlt ; hlt
.subsections_via_symbols
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.weak_definition ___i686.get_pc_thunk.bx
.private_extern ___i686.get_pc_thunk.bx
___i686.get_pc_thunk.bx:
movl (%esp), ëx
ret
------
As you can see - the function call is inlined - there is no call to
macfn1 - the printf has been inlined. However, the compiler is still
embedding a ".globl _macfn1" version of the function. When I build
with a copy of this .C file included in the build (with macfn2
renamed to macfn3) - the linker err's out with this:
macbook:~/dev/inline chris$ make
gcc -o macinline macmain.o macinline1.o macinline2.o
/usr/bin/ld: multiple definitions of symbol _macfn1
macinline1.o definition of _macfn1 in section (__TEXT,__text)
macinline2.o definition of _macfn1 in section (__TEXT,__text)
collect2: ld returned 1 exit status
make: *** [macinline] Error 1
Honestly - that is what I would expect? If a global function is
defined in multiple .o files, how is the linker supposed to know that
those functions are all the same - certainly not by the name?
Since, by definition:
1) An inline function is short
2) Its definition must be available to anyone who calls it
I always define inline functions in their header (with no separate
declaration).
If the inline keyword is in the declaration, there is no need to
declare them static -- in fact this will cause code bloat if they
are referenced from multiple files and not inlined.
Simply using inline will cause the linker to keep just one
implementation, but for this to happen, all declarations must be
inline.
I do not see this happening. In fact, I see nothing in the generated
assembly that would clue the linker into the fact that the function
was inlined - and again, this is not surprising to me - since inline
is a compile-time operation, not a link-time operation.
In fact, here is a statement from the gcc inline doc pointer from
Colin ...
"When an inline function is not static, then the compiler must assume
that there may be calls from other source files; since a global
symbol can be defined only once in any program, the function must not
be defined in the other source files, so the calls therein cannot be
integrated. Therefore, a non-static inline function is always
compiled on its own in the usual fashion."
Later,
-Chris
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden