yes I think you are right, it is same with msvc v6.
I don't know well the tcc code, but I don't think it inline
functions (like a macro, should be complicated to do).
So defining inline (alone) as static maybe a good idea ?
int tccgen.c line 3042
change:
case TOK_INLINE1:
case TOK_INLINE2:
case TOK_INLINE3:
t |= VT_INLINE;
next();
break;
to
case TOK_INLINE1:
case TOK_INLINE2:
case TOK_INLINE3:
if (!(t & VT_EXTERN)) // if extern
defined ignore 'inline'
t |= VT_INLINE | VT_STATIC; // if not extern, set
static as default
next();
break;
and line 3030
change
case TOK_EXTERN:
t |= VT_EXTERN;
to
case TOK_EXTERN:
{
t |= VT_EXTERN;
t &= ~VT_INLINE; //
remove 'inline'
}
I don't know if some more changes are required ?
Pierre
Le 11/12/2013 23:22, Rob a écrit :
'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
_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel
|