Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Port from Win to OSX with Inline functions



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 %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
call ___i686.get_pc_thunk.bx
"L00000000001$pb":
leal LC0-"L00000000001$pb"(%ebx), %eax
movl %eax, (%esp)
call L_puts$stub
addl $20, %esp
popl %ebx
popl %ebp
ret
.cstring
LC1:
.ascii "macfn2-->\0"
.text
.globl _macfn2
_macfn2:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
call ___i686.get_pc_thunk.bx
"L00000000002$pb":
leal LC1-"L00000000002$pb"(%ebx), %eax
movl %eax, (%esp)
call L_puts$stub
leal LC0-"L00000000002$pb"(%ebx), %eax
movl %eax, (%esp)
call L_puts$stub
addl $20, %esp
popl %ebx
popl %ebp
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), %ebx
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:
http://lists.apple.com/mailman/options/darwin-dev/email@hidden

This email sent to email@hidden
References: 
 >Port from Win to OSX with Inline functions (From: Chris Edgington <email@hidden>)
 >Re: Port from Win to OSX with Inline functions (From: Chris Edgington <email@hidden>)
 >Re: Port from Win to OSX with Inline functions (From: Steve Sisak <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.