tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] RE :Re: inline functions


From: Thomas Preud'homme
Subject: Re: [Tinycc-devel] RE :Re: inline functions
Date: Wed, 11 Dec 2013 21:06:39 +0800
User-agent: KMail/4.11.3 (Linux/2.6.38-ac2-ac100; KDE/4.11.3; armv7l; ; )

Le mercredi 11 décembre 2013, 09:28:07 Christian JULLIEN a écrit :
> > Normally an inline must be locally defined ?
> 
> Makes sense.
> 
> NO! inline keyword is only a hint to the compiler that a function is
> supposed small enough to be inlined. It's perfectly legal for a compiler to
> ignore this hint if it thinks it's too complicated to inline this code. C
> standard does not specify the minimal complexity to insure an inline
> function is actually inlined.
> 
> From function definition point of view, inlined keyword does not play a
> specific role for function visibility.

I knew about the fact that it is a hint and I knew even when inlined, the 
function still needs to be output in case its address is used. However I 
forgot about the other details. I stand corrected, thanks.

I remembered extern and inline has a special meaning as well but I forgot so I 
checked online and I think the documentation of gcc [0] explains pretty well 
how inline behave. I'm a bit surprised though because I thought the special 
meaning of extern inline was not in the standard but something gcc specific. 
Again, I stand corrected.

[0] http://gcc.gnu.org/onlinedocs/gcc/Inline.html

So Pierre, you either want static inline or extern inline.
> 
> More precisely:
> 
> inline void f() { ... }
> is like
> void f() { .. }
> and as an external visibility.
> 
> Even not commonly used a DEFINITION like
> 
> void f() { ... }
> is in fact
> extern void f() { ... }
> 
> Because extern is the default linkage either for a variable or a function.
> (extern int i = 100; is not a declaration but a legal definition)

Yes, indeed.

> 
> It means that if you include this definition form 2 translation units you
> will have different results depending if inlined function has been inlined
> or not.

I don't think so. Even inlined, the function is still generated on its own for 
address comparison. I've tried a quick test:

21:03 address@hidden ~/tmp/inline% cat inline.h
inline int inc(int v)
{
        return v + 1;
}
21:03 address@hidden ~/tmp/inline% cat inline.c
#include <inline.h>

int foo(int a, int b)
{
        return inc(a) + inc(b);
}
21:03 address@hidden ~/tmp/inline% cat main.c
#include <inline.h>

int main(void)
{
        return inc(foo(1, 2));
}

21:03 address@hidden ~/tmp/inline% gcc -I. -c inline.c main.c        
21:04 address@hidden ~/tmp/inline% LANG=C gcc -O3 -o main inline.o main.o
main.o: In function `inc':
main.c:(.text+0x0): multiple definition of `inc'
inline.o:inline.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
zsh: exit 1     LANG=C colorgcc -O3 -o main inline.o main.o

> 
> If you want to avoid problems when you define an inlined function in a .h is
> to declare this function static. This way, if compiler is not able to
> inline function, the two or more translation units using it will have their
> own static copy that will make linker happy.

Or extern inline which has a slightly different meaning. With static inline you 
need to provide two implementation of the function, one with static inline in 
the header, and one normal implementation somewhere else in case there is a 
call that cannot be inlined or if the address of the function is used. With 
extern inline you make it clear that you want the function inlined no matter 
what. At least that is my understanding after a quick read but again, I might 
have read too quickly.

> 
> Christian

Thanks Christian for your valuable input.

Best regards,

Thomas



reply via email to

[Prev in Thread] Current Thread [Next in Thread]