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: Rob
Subject: Re: [Tinycc-devel] RE :Re: inline functions
Date: Wed, 11 Dec 2013 22:22:30 +0000 (GMT)
User-agent: Alpine 2.02 (DEB 1266 2009-07-14)

'inline' alone should not generate code, I'm pretty certain. It's an
inline-only definition. If it can't be inlined, you get a linker error.

For example:

inline int f()
{
        return 3;
}

int main()
{
        return f();
}

A standalone function named 'f' will never appear in the generated code.
If the compiler inlines 'f' into main, the program will link. If the
compiler doesn't or can't inline 'f', you'll get a linker error.

So we get a linker error with 'gcc -std=c99 -O0', but the program links
fine with 'gcc -std=c99 -O1', as f isn't referenced (since it's
inlined by an optimiser).

Also, I checked - gcc defaults to -std=gnu89, which means gnu89 inline
semantics, so when testing, make sure you give it '-std=c99'.

Clang exhibits the same behaviour w.r.t. inline, so I'm pretty sure I've
interpreted the standard correctly. Note that clang defaults to C99.


Thanks,
Rob


On Wed, 11 Dec 2013, Pierre wrote:
So inline alone should export nothing if not refferenced (with code or forward 
declared), and at most, create a static function if cannot be inlined ?

And an 'extern inline ' simply ignore 'inline' ?


Le 11/12/2013 22:33, Rob a écrit :
      On Wed, 11 Dec 2013, Thomas Preud'homme wrote:
            Le mercredi 11 décembre 2013, 09:28:07 Christian JULLIEN a écrit :
            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

                  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.



      There are very subtle differences and with gcc I'm pretty sure you have
      to specify -std=c99 otherwise it defaults to gnu89 which has different,
      GNU inline semantics.

      'inline', unfortunately is not just a hint to the compiler. There are a
      few checks compilers have to perform too.


      So we have three forms of inline:

      extern inline void func() { ... } // 1
      static inline void func() { ... } // 2
             inline void func() { ... } // 3


      The first form, 'extern inline', will always cause a
      standalone/non-inlined function to be emitted, just as if 'inline'
      wasn't present. The inline modifier here simply acts as a hint that this
      function may be inlined.

      The second form, 'static inline', will cause function code to be
      emitted, but the compiler may omit this if it knows the function is
      never used (since it's static, it's not called from another translation
      unit). Again, 'inline' acts only as a hint.

      The final form, 'inline' without a storage class is where we have
      special handling. In this case, standalone function code is never
      emitted, this version is _only_ to be used for inline substitution.


      For the final form to take affect, none of the declarations of `func'
      must mention extern, for example:


      inline f();
      inline f();
      extern inline f(); // this causes `f' to be in form 2
      inline f() { ... }



      At least, that's what I've gathered from the standard and various
      searches.


      Thanks, Rob


_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel




reply via email to

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