Inline functions have addresses?

Discussion in 'C++' started by Ravi, Jul 23, 2010.

  1. Ravi

    Ravi Guest

    In section 7.1.1 of the book The C++ Programming language the author
    mentions -

    "inline function still has a unique variable and so do the static
    variables of an inline function"

    I am confused. If I have inline function then it can't have address.
    Does this happen in C also?
     
    Ravi, Jul 23, 2010
    #1
    1. Advertising

  2. On Jul 23, 9:01 am, Ravi <> wrote:
    > In section 7.1.1 of the book The C++ Programming language the author
    > mentions -
    >
    > "inline function still has a unique variable and so do the static
    > variables of an inline function"
    >
    > I am confused. If I have inline function then it can't have address.
    > Does this happen in C also?


    If you take the address of an inlined function, the compiler will
    outline it somewhere and give you the address of that outlined
    function.

    C inline functions are subtly different, and I'll let someone else
    tackle that part of your question.

    -Howard
     
    Howard Hinnant, Jul 23, 2010
    #2
    1. Advertising

  3. Ravi

    SG Guest

    On 23 Jul., 15:01, Ravi wrote:
    >
    > I am confused. If I have inline function then it can't have address.


    Sure it can. Think of inline as an additional property of a function
    and forget about what a compiler might or might not do w.r.t. actual
    inlining. An "inline function" is just like a normal function and it
    has an address as well (at least you can ask for it). But there are
    two big differences in terms of semantics (I can think of):

    - The one definition rule allows multiple definitions of the same
    inline function (at most one definition per translation unit)
    as long as the definitions are equivalent. This is not allowed
    for non-inline functions.

    - Any use of an inline function *requires* a definition of the
    function in the translation unit where it is used. This is not
    necessary for non-inline functions.

    For a compiler that handles translation units independently (like most
    compilers do), the benifits of these rules are:

    - Inlining of an inline function is fairly easy because the
    translation unit includes the function's definition.

    - The compiler doesn't need to create a distinct symbol for the
    inline function unless its address is taken or the function
    is used but not actually inlined.


    > Does this happen in C also?


    In C the inline keyword is just a decoration. As far as I can tell, it
    doesn't have any effect on the semantics of your program (unlike in C+
    +). To avoid multiple definition errors C programmers often use inline
    in combination with static which makes the function to have internal
    linkage.


    Cheers!
    SG
     
    SG, Jul 23, 2010
    #3
  4. Ravi wrote:
    > In section 7.1.1 of the book The C++ Programming language the author
    > mentions -
    >
    > "inline function still has a unique variable and so do the static
    > variables of an inline function"
    >
    > I am confused. If I have inline function then it can't have address.
    > Does this happen in C also?


    You are indeed confused.

    Inline functions are... well, _functions_. And as all functions, they
    have addresses. Where did you get that strange idea that an inline
    function "can't have address"?

    The fact that the body of inline function can be _inlined_ at some (or
    all) points from where this function is called has absolutely no effect
    on the function itself. In other words, actual _inlining_ is something
    that affects specific _calls_ to the function, but has no effect on the
    functions itself. In particular, there's nothing to prevent an inline
    function from having an address.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Jul 23, 2010
    #4
  5. On 23-07-2010 20:00, Andrey Tarasevich wrote:
    > Ravi wrote:
    >> In section 7.1.1 of the book The C++ Programming language the author
    >> mentions -
    >>
    >> "inline function still has a unique variable and so do the static
    >> variables of an inline function"
    >>
    >> I am confused. If I have inline function then it can't have address.
    >> Does this happen in C also?

    >
    > You are indeed confused.
    >
    > Inline functions are... well, _functions_. And as all functions, they
    > have addresses. Where did you get that strange idea that an inline
    > function "can't have address"?
    >

    Not strange. What is reason for keeping not used code inside binary ?
    (if all is inlined)

    Regards

    Marek
     
    Marek Borowski, Jul 23, 2010
    #5
  6. Ravi

    Bo Persson Guest

    Marek Borowski wrote:
    > On 23-07-2010 20:00, Andrey Tarasevich wrote:
    >> Ravi wrote:
    >>> In section 7.1.1 of the book The C++ Programming language the
    >>> author mentions -
    >>>
    >>> "inline function still has a unique variable and so do the static
    >>> variables of an inline function"
    >>>
    >>> I am confused. If I have inline function then it can't have
    >>> address. Does this happen in C also?

    >>
    >> You are indeed confused.
    >>
    >> Inline functions are... well, _functions_. And as all functions,
    >> they have addresses. Where did you get that strange idea that an
    >> inline function "can't have address"?
    >>

    > Not strange. What is reason for keeping not used code inside binary
    > ? (if all is inlined)
    >


    If you take its address, it must have one. :)

    Otherwise the unused code can be removed.


    Bo Persson
     
    Bo Persson, Jul 23, 2010
    #6
  7. Marek Borowski wrote:
    > On 23-07-2010 20:00, Andrey Tarasevich wrote:
    >> Ravi wrote:
    >>> In section 7.1.1 of the book The C++ Programming language the author
    >>> mentions -
    >>>
    >>> "inline function still has a unique variable and so do the static
    >>> variables of an inline function"
    >>>
    >>> I am confused. If I have inline function then it can't have address.
    >>> Does this happen in C also?

    >> You are indeed confused.
    >>
    >> Inline functions are... well, _functions_. And as all functions, they
    >> have addresses. Where did you get that strange idea that an inline
    >> function "can't have address"?
    >>

    > Not strange. What is reason for keeping not used code inside binary ?
    > (if all is inlined)


    Firstly, nobody said that it has to be kept in the final binary, if it
    is really not used.

    Secondly, one reason to keep it (at least at some intermediate stages of
    the compilation) is that inline functions in C++ (just like any other
    functions) have external linkage by default. Some implementations might
    decide to generate and keep the unused body for a while, until the
    compilation is pretty mush done, and it is finally known whether the
    body is actually used.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Jul 23, 2010
    #7
  8. SG <> wrote:
    > In C the inline keyword is just a decoration. As far as I can tell, it
    > doesn't have any effect on the semantics of your program (unlike in C+
    > +). To avoid multiple definition errors C programmers often use inline
    > in combination with static which makes the function to have internal
    > linkage.


    Does that mean it's not possible in C to do this (and have it work in
    the same way)?

    inline void foo()
    {
    static int counter = 0;
    ++counter;
    ...
    }
     
    Juha Nieminen, Jul 27, 2010
    #8
  9. Ravi

    Ian Collins Guest

    On 07/27/10 07:19 PM, Juha Nieminen wrote:
    > SG<> wrote:
    >> In C the inline keyword is just a decoration. As far as I can tell, it
    >> doesn't have any effect on the semantics of your program (unlike in C+
    >> +). To avoid multiple definition errors C programmers often use inline
    >> in combination with static which makes the function to have internal
    >> linkage.

    >
    > Does that mean it's not possible in C to do this (and have it work in
    > the same way)?
    >
    > inline void foo()
    > {
    > static int counter = 0;
    > ++counter;
    > ...
    > }


    Considering the "as if" rule, it must.

    --
    Ian Collins
     
    Ian Collins, Jul 27, 2010
    #9
  10. Ian Collins <> wrote:
    > On 07/27/10 07:19 PM, Juha Nieminen wrote:
    >> SG<> wrote:
    >>> In C the inline keyword is just a decoration. As far as I can tell, it
    >>> doesn't have any effect on the semantics of your program (unlike in C+
    >>> +). To avoid multiple definition errors C programmers often use inline
    >>> in combination with static which makes the function to have internal
    >>> linkage.

    >>
    >> Does that mean it's not possible in C to do this (and have it work in
    >> the same way)?
    >>
    >> inline void foo()
    >> {
    >> static int counter = 0;
    >> ++counter;
    >> ...
    >> }

    >
    > Considering the "as if" rule, it must.


    It must what?
     
    Juha Nieminen, Jul 27, 2010
    #10
  11. Ravi

    SG Guest

    On 27 Jul., 09:19, Juha Nieminen <> wrote:
    > SG <> wrote:
    > > In C the inline keyword is just a decoration. As far as I can tell, it
    > > doesn't have any effect on the semantics of your program (unlike in C+
    > > +). To avoid multiple definition errors C programmers often use inline
    > > in combination with static which makes the function to have internal
    > > linkage.

    >
    >   Does that mean it's not possible in C to do this (and have it work in
    > the same way)?
    >
    >     inline void foo()
    >     {
    >         static int counter = 0;
    >         ++counter;
    >         ...
    >     }


    As far as I know, in C, inline functions with _external_linkage_ are
    subject to some restrictions. One of these restrictions is that they
    are not allowed to have static variables. So, your example is not
    valid C99.
     
    SG, Jul 27, 2010
    #11
  12. Ravi

    James Kanze Guest

    On Jul 27, 8:19 am, Juha Nieminen <> wrote:
    > SG <> wrote:
    > > In C the inline keyword is just a decoration. As far as I can tell, it
    > > doesn't have any effect on the semantics of your program (unlike in C+
    > > +). To avoid multiple definition errors C programmers often use inline
    > > in combination with static which makes the function to have internal
    > > linkage.


    > Does that mean it's not possible in C to do this (and have it work in
    > the same way)?


    > inline void foo()
    > {
    > static int counter = 0;
    > ++counter;
    > ...
    > }


    IIRC (and this is just from memory---I don't have my copy of the
    C standard around to check), the above is undefined behavior in
    C (but not in C++, where the compiler is required to make it
    work).

    --
    James Kanze
     
    James Kanze, Jul 27, 2010
    #12
  13. James Kanze <> wrote:
    >> Does that mean it's not possible in C to do this (and have it work in
    >> the same way)?

    >
    >> inline void foo()
    >> {
    >> static int counter = 0;
    >> ++counter;
    >> ...
    >> }

    >
    > IIRC (and this is just from memory---I don't have my copy of the
    > C standard around to check), the above is undefined behavior in
    > C (but not in C++, where the compiler is required to make it
    > work).


    Is there a good reason for this?
     
    Juha Nieminen, Jul 27, 2010
    #13
  14. Ravi

    SG Guest

    On 27 Jul., 19:48, Juha Nieminen <> wrote:
    > James Kanze <> wrote:
    > >>   Does that mean it's not possible in C to do this (and have it work in
    > >> the same way)?

    >
    > >>     inline void foo()
    > >>     {
    > >>         static int counter = 0;
    > >>         ++counter;
    > >>         ...
    > >>     }

    >
    > > IIRC (and this is just from memory---I don't have my copy of the
    > > C standard around to check), the above is undefined behavior in
    > > C (but not in C++, where the compiler is required to make it
    > > work).

    >
    >   Is there a good reason for this?


    From http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
    (draft of C99+TC1+TC2+TC3 from 2007)

    6.7.4/3:
    "An inline definition of a function with external linkage shall not
    contain a definition of a modifiable object with static storage
    duration, and shall not contain a reference to an identifier with
    internal linkage."

    6.7.4/6:
    "[...] For a function with external linkage, the following
    restrictions apply: If a function is declared with an inline
    function specifier, then it shall also be defined in the same
    translation unit. 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. An inline definition
    does not provide an external definition for the function, and does
    not forbid an external definition in another translation unit.
    An inline definition provides an alternative to an external
    definition, which a translator may use to implement any call to
    the function in the same translation unit. It is unspecified
    whether a call to the function uses the inline definition or the
    external definition."

    If I understand this correctly, inline in C is more restrictive than
    in C++ (w.r.t. static variables for example) and you have to (or
    should) provide an "external definition" of an inline function with
    external linkage in exactly one translation unit like this:

    ----------8<----------

    // foo.h
    #ifndef FOO_H_INCLUDED
    #define FOO_H_INCLUDED

    inline int add(int a, int b) {return a+b;}

    #endif

    ----------8<----------

    // foo.c
    #include "foo.h"

    // This declaration makes the definition from the
    // header an "external definition" in *this* TU.
    extern inline int add(int,int);

    ----------8<----------

    Did I get this right?

    Cheers!
    SG
     
    SG, Jul 28, 2010
    #14
  15. Ravi

    SG Guest

    On 28 Jul., 10:55, SG wrote:
    > ----------8<----------
    >
    >   // foo.h
    >   #ifndef FOO_H_INCLUDED
    >   #define FOO_H_INCLUDED
    >
    >   inline int add(int a, int b) {return a+b;}
    >
    >   #endif
    >
    > ----------8<----------
    >
    >   // foo.c
    >   #include "foo.h"
    >
    >   // This declaration makes the definition from the
    >   // header an "external definition" in *this* TU.
    >   extern inline int add(int,int);
    >
    > ----------8<----------
    >
    > Did I get this right?


    It seems so. But using the header in another file and compiling
    +linking it with GCC like this:

    > gcc -o test test.c foo.c


    leads to the following error:

    test.c: multiple definition of 'add'
    foo.c: first definition here

    Now, if I add the option "-std=c99" this goes away and it compiles
    +links just fine. It seems that GCC in its default mode doesn't
    respect the C99 rules regarding inline. It doesn't seem to distinguish
    between "inline definition" and "extern definition" and always
    generates a symbol for the function (which explains the linker error)
    *unless* you specifically enable the C99 mode.

    Ok, so, in C99 you don't *have* to use inline in combination with
    static and inline is not just a "decoration" but comes with its own
    set of rules. I stand corrected.

    Cheers!
    SG
     
    SG, Jul 28, 2010
    #15
  16. Ravi

    James Kanze Guest

    On Jul 27, 6:48 pm, Juha Nieminen <> wrote:
    > James Kanze <> wrote:
    > >> Does that mean it's not possible in C to do this (and have it work in
    > >> the same way)?


    > >> inline void foo()
    > >> {
    > >> static int counter = 0;
    > >> ++counter;
    > >> ...
    > >> }


    > > IIRC (and this is just from memory---I don't have my copy of the
    > > C standard around to check), the above is undefined behavior in
    > > C (but not in C++, where the compiler is required to make it
    > > work).


    > Is there a good reason for this?


    Make things easier for the compiler writer.

    Making a local static work in an inline function with external
    linkage requires some special handling. The same special
    handling is needed for templates in C++, so making them work in
    C++ is basically free. In C, the compiler would have to add
    this special handling, just for static local variables in inline
    functions.

    --
    James Kanze
     
    James Kanze, Jul 28, 2010
    #16
  17. James Kanze <> wrote:
    >> Is there a good reason for this?

    >
    > Make things easier for the compiler writer.


    I have always had the opinion that programs (in this particular case
    compilers) should make the user's life simpler, not the other way around
    (iow. restricting the user from using a logical feature which the language
    could obviously support because such a restriction makes writing a compiler
    easier is going in the wrong direction in the who-is-helping-who line).

    (This is the same reason why I strongly oppose eg. MathML, compared to
    something like LaTeX equations. MathML exists to make it easier for
    programmers to write programs which parse mathematical expressions, at
    the cost of greatly complexifying the work of the user, who needs to
    write the mathematical expression in MathML. LaTeX goes the other way
    around: It makes it as easy as possible for the user to write mathematical
    expressions, at the cost of greatly complexifying the program that parses
    the expression. This is the correct direction. Programs are there to help
    users, not the other way around.)
     
    Juha Nieminen, Jul 28, 2010
    #17
  18. Ravi

    James Kanze Guest

    On Jul 28, 6:06 pm, Juha Nieminen <> wrote:
    > James Kanze <> wrote:
    > >> Is there a good reason for this?


    > > Make things easier for the compiler writer.


    > I have always had the opinion that programs (in this particular case
    > compilers) should make the user's life simpler, not the other way around
    > (iow. restricting the user from using a logical feature which the language
    > could obviously support because such a restriction makes writing a compiler
    > easier is going in the wrong direction in the who-is-helping-who line).


    I tend to agree. In the case of C: historically, C was first
    designed for very small systems, and implemented by very small
    teams (two or three people). If you didn't make the compiler
    simpler for for the compiler writer, you didn't get a compiler.
    Today, this still influences the "taste" of C.

    With regards to inline functions, I sort of agree with the
    C committee. The mechanism is rather heavy, and requiring it
    uniquely for inline functions does seem a bit overdoing things.
    (But then, given the size and performance of modern hardware,
    I don't see the point of C anyway. Anything C can do, C++ can
    do better.)

    --
    James Kanze
     
    James Kanze, Jul 29, 2010
    #18
  19. James Kanze <> wrote:
    > With regards to inline functions, I sort of agree with the
    > C committee. The mechanism is rather heavy, and requiring it
    > uniquely for inline functions does seem a bit overdoing things.


    Strictly speaking, isn't it something that complicates the *linker*
    rather than the compiler itself (other than the compiler having to
    generate instructions for the linker to merge the static variables
    into one)?
     
    Juha Nieminen, Jul 29, 2010
    #19
  20. Ravi

    SG Guest

    On 29 Jul., 14:27, Juha Nieminen wrote:
    > James Kanze <> wrote:
    > > With regards to inline functions, I sort of agree with the
    > > C committee.  The mechanism is rather heavy, and requiring it
    > > uniquely for inline functions does seem a bit overdoing things.

    >
    >   Strictly speaking, isn't it something that complicates the *linker*
    > rather than the compiler itself (other than the compiler having to
    > generate instructions for the linker to merge the static variables
    > into one)?


    Yes, I think that's exactly the case. The rules of C99 inline seem to
    easily support "simple linkers" whereas a straight forward C++
    implementation would use a linker that simply "merges" certain
    multiple definitions (inline functions, function templates, static
    members of class templates) and complains about others (non-inline non-
    template functions, other static objects). Apparently, the GCC C++
    compiler marks some symbols as "weak" to tell the linker to ignore
    multiple definitions. Of course, your object file format has to
    support this as well. I've already seen an embedded "C linker" choke
    on compiled C++ code. It wasn't able to cope with an inline function.

    Cheers!
    SG
     
    SG, Jul 29, 2010
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    483
  2. Daniel Vallstrom
    Replies:
    2
    Views:
    2,008
    Kevin Bracey
    Nov 21, 2003
  3. Prafull Soni

    Can we have inline functions in c?

    Prafull Soni, Mar 4, 2005, in forum: C Programming
    Replies:
    15
    Views:
    517
    Joe Wright
    Mar 7, 2005
  4. namespace1
    Replies:
    3
    Views:
    930
  5. Rahul
    Replies:
    3
    Views:
    474
    James Kanze
    Feb 28, 2008
Loading...

Share This Page