#1900 calling inline function

open
nobody
Front-end
5
2015-03-25
2011-12-23
No

There is a problem when the definition of an inline function is feter the call. The following code shows the problem

inline void f(void);

void g1(void)
{
f();
}

inline void f(void)
{
}

void g2(void)
{
f();
}

The call to f() in g2() works as intended, but the one in g1() does not. This problem can be reprodiced in sdcc revision #7126.

Philipp

Discussion

  • Maarten Brock

    Maarten Brock - 2011-12-23

    Can you please be a bit more elaborate? What does "not work" mean? Do you get an error or is it just not inlined? I assume it perfectly executes "nothing".

     
  • Philipp Klaus Krause

    The call is neither inlined, nor is a function body being generated, I thus get

    ?ASlink-Warning-Undefined Global '_f' referenced by module 'test'

    Philipp

     
  • Maarten Brock

    Maarten Brock - 2011-12-23

    That seems correct to me.

    The call does not need to be inlined. And the inline definition with external linkage should not generate an external definition (a function body implementation). You must provide one. The inline definition can only be used for inline replacement.

     
  • Maarten Brock

    Maarten Brock - 2011-12-23
    • labels: --> C-Front End
    • milestone: --> 100455
    • assigned_to: nobody --> maartenbrock
    • status: open --> closed-rejected
     
  • Philipp Klaus Krause

    • status: closed-rejected --> open
     
  • Philipp Klaus Krause

    After re-reading the standard, it seems you are right: In my example the definition of f() is an inline definition which only providedes an alternative to a potentially existing external definition and the compiler is free to use the inline definition (as it does for g2()) or the external one (as it does for g1()).

    The following is bases on my still shaky understanding of the standard, so I might be wrong again:

    Making a small change to the testcase IMO makes it a bug: Add the following line at the end of the source file:

    extern void f(void);

    Now, according to the standard, we still have a definition of an inline function, but it no longer is an inline definition (verse 1540 (C99) "If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition." no longer applies. We even have an external definition now, which could be used from other translation units. Still, we might inline the calls to f() or not, but we no longer can produce a link error.

    Another option would be to make f static and add a

    static void f(void);

    at the end of the file. Now we do not have an external definition, but it is not an inline definition either. WE have the option of inlining the calls or not, but we can't give a link error and we cannot create a definition visible by other translation units.

    In all these cases, sdcc still gives the original error message "?ASlink-Warning-Undefined Global '_f' referenced by module 'test'".

    Philipp

     
  • Philipp Klaus Krause

    Sorry, the static case seems to work, but the cases of adding
    extern inline void f(void);
    or
    extern void f(void);
    or
    void f(void);
    do not.

    Philipp

     
  • Maarten Brock

    Maarten Brock - 2011-12-23
    • assigned_to: maartenbrock --> nobody
    • milestone: 100455 -->
     
  • Maarten Brock

    Maarten Brock - 2011-12-23

    Both the inline definition case and static inline case are already tested by regression test inline.c. The external definition case apparently is not.

    But I agree with you that the description in the spec is pretty difficult. That is probably also why many other compilers seem to get it wrong.

     
  • Ben Shi

    Ben Shi - 2015-03-25
    • Category: --> Front-end
     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks