Function Pointers and Inlining

Discussion in 'C++' started by Mat Booth, Mar 22, 2005.

  1. Mat Booth

    Mat Booth Guest

    If I call an inline member function through a member function pointer,
    will that function be inlined?

    I imagine it wouldn't because the function that's pointed to isn't known
    until run-time, is that correct?

    Cheers.
    Mat Booth, Mar 22, 2005
    #1
    1. Advertising

  2. Mat Booth

    David White Guest

    "Mat Booth" <> wrote in message
    news:d1o0qb$mro$...
    > If I call an inline member function through a member function pointer,
    > will that function be inlined?
    >
    > I imagine it wouldn't because the function that's pointed to isn't known
    > until run-time, is that correct?


    It might be that in some cases the compiler is smart enough to know the
    identity of the function whose address must be in the pointer, or that it
    can do away with the pointer altogether and just inline the function. In
    other cases it couldn't possibly know what the pointer contains and would
    have to indirectly call a non-inlined instance of the function.

    I tried this on VC++ 6.0, optimized for speed:

    int N;

    inline void f()
    {
    ++N; // do some work or no code is generated
    }

    int main()
    {
    f();
    void (*pf)() = &f;
    (*pf)();
    }

    The generated code was:

    inc dword ptr [N]
    jmp f
    f:
    inc dword ptr [N]
    ret

    I don't know why it bothered with the redundant jump, but the compiler
    clearly saw that no call was needed. In principle, a pointer to an inlined
    class member function is no different, though this compiler wasn't smart
    enough to generate such small code when I tried the member-function
    equivalent. It ignored the pointer and called the non-inlined function
    directly.

    DW
    David White, Mar 22, 2005
    #2
    1. Advertising

  3. Mat Booth

    invincible Guest

    test mail
    plz ignore

    "Mat Booth" <> wrote in message
    news:d1o0qb$mro$...
    > If I call an inline member function through a member function pointer,
    > will that function be inlined?
    >
    > I imagine it wouldn't because the function that's pointed to isn't known
    > until run-time, is that correct?
    >
    > Cheers.
    invincible, Mar 22, 2005
    #3
  4. invincible schrieb:
    > test mail


    Not a mail, but an article.

    > plz ignore


    For this kind of posting, there is alt.test and similar groups.
    comp.lang.c++ is not one of them.

    >
    > "Mat Booth" <> wrote in message
    > news:d1o0qb$mro$...


    Don't reply to an article unless you really reply to it.

    Cheers,
    Malte
    Malte Starostik, Mar 22, 2005
    #4
  5. "Mat Booth" <> wrote in message
    news:d1o0qb$mro$...
    > If I call an inline member function through a member function pointer,
    > will that function be inlined?
    >
    > I imagine it wouldn't because the function that's pointed to isn't known
    > until run-time, is that correct?


    Any function which has its address taken during the course of the program
    will never be inlined.

    - JFA1
    James Aguilar, Mar 22, 2005
    #5
  6. Mat Booth

    Howard Guest

    "James Aguilar" <> wrote in message
    news:d1oec7$jhl$...
    >
    > "Mat Booth" <> wrote in message
    > news:d1o0qb$mro$...
    >> If I call an inline member function through a member function pointer,
    >> will that function be inlined?
    >>
    >> I imagine it wouldn't because the function that's pointed to isn't known
    >> until run-time, is that correct?

    >
    > Any function which has its address taken during the course of the program
    > will never be inlined.
    >
    > - JFA1


    Never? I don't think that's correct. If I recall, the implementation is
    free to inline those calls which it is able to inline. But it must also
    provide a non-inline version which can be called normally. It's not an
    all-or-nothing thing, but is handled on a case-by-case basis. At least,
    that's my understanding.

    -Howard
    Howard, Mar 22, 2005
    #6
  7. "Howard" <> wrote in message
    news:YzY%d.162941$...
    > Never? I don't think that's correct. If I recall, the implementation is free
    > to inline those calls which it is able to inline. But it must also provide a
    > non-inline version which can be called normally. It's not an all-or-nothing
    > thing, but is handled on a case-by-case basis. At least, that's my
    > understanding.


    I've been wrong before, but I think I read something about how if you take the
    address of a particular function, that function won't be inlined elsewhere. A
    test shows . . .

    --- CODE ---
    inline
    void inlineTest(int &i) {
    i += 5;
    }

    int main()
    {
    int i = 2;
    void (*testPtr)(int &) = &inlineTest;
    testPtr(i);

    inlineTest(i);
    return 0;
    }

    --- CODE ---

    This compiled with -S and on g++ gives this assembly code:

    --- CODE ---
    movl $2, -4(%ebp)
    movl $__Z10inlineTestRi, -8(%ebp)
    leal -4(%ebp), %eax
    movl %eax, (%esp)
    movl -8(%ebp), %eax
    call *%eax
    leal -4(%ebp), %eax
    movl %eax, (%esp)
    call __Z10inlineTestRi ;LINK 1
    movl $0, %eax
    --- CODE ---

    I think that if it worked as you say, LINK 1 would be addl $5, %eax or something
    like that. On the other hand, when I get the assembly compiling with -O2, crazy
    stuff happens and I can't read it.

    - JFA1
    James Aguilar, Mar 22, 2005
    #7
  8. James Aguilar wrote:
    > "Howard" <> wrote in message
    > news:YzY%d.162941$...
    >
    >>Never? I don't think that's correct. If I recall, the implementation is free
    >>to inline those calls which it is able to inline. But it must also provide a
    >>non-inline version which can be called normally. It's not an all-or-nothing
    >>thing, but is handled on a case-by-case basis. At least, that's my
    >>understanding.

    >
    >
    > I've been wrong before, but I think I read something about how if you take the
    > address of a particular function, that function won't be inlined elsewhere. A
    > test shows . . .
    >
    > --- CODE ---

    [...]
    > --- CODE ---
    >
    > I think that if it worked as you say, LINK 1 would be addl $5, %eax or something
    > like that. On the other hand, when I get the assembly compiling with -O2, crazy
    > stuff happens and I can't read it.


    You're arguing different points here. Howard says what the Standard says.
    You are demonstrating what you've observed with the compilers you have.
    Both are correct but they don't contradict each other.

    The Standard does not mandate either behaviour. It should be reasonably
    apparent that if somebody takes the address of a function, the body has to
    exist somewhere otherwise what would the address point to? However, the
    act of putting a copy of the function body with all necessary adjustments
    into the code instead of a call to that function (known as "inlining") is
    totally up to the compiler. It doesn't have to do it even if you use the
    'inline' keyword.

    Between two extremes: inlining all [static] calls to that function and
    also providing a body elsewhere if the address is taken *and* not inlining
    the function at all, is where the behaviour of a compliant compiler lies.
    You should see by now that there is nothing to argue about.

    V
    Victor Bazarov, Mar 22, 2005
    #8
  9. Mat Booth

    Rolf Magnus Guest

    James Aguilar wrote:

    > "Howard" <> wrote in message
    > news:YzY%d.162941$...
    >> Never? I don't think that's correct. If I recall, the implementation is
    >> free
    >> to inline those calls which it is able to inline. But it must also
    >> provide a
    >> non-inline version which can be called normally. It's not an
    >> all-or-nothing
    >> thing, but is handled on a case-by-case basis. At least, that's my
    >> understanding.

    >
    > I've been wrong before, but I think I read something about how if you take
    > the address of a particular function, that function won't be inlined
    > elsewhere.


    It's rather the other way round. If you take a pointer, a non-inline version
    of the function must be created. However, that doesn't mean that the
    function cannot be inlined anymore.

    > A test shows . . .
    >
    > --- CODE ---
    > inline
    > void inlineTest(int &i) {
    > i += 5;
    > }
    >
    > int main()
    > {
    > int i = 2;
    > void (*testPtr)(int &) = &inlineTest;
    > testPtr(i);
    >
    > inlineTest(i);
    > return 0;
    > }
    >
    > --- CODE ---
    >
    > This compiled with -S and on g++ gives this assembly code:
    >
    > --- CODE ---
    > movl $2, -4(%ebp)
    > movl $__Z10inlineTestRi, -8(%ebp)
    > leal -4(%ebp), %eax
    > movl %eax, (%esp)
    > movl -8(%ebp), %eax
    > call *%eax
    > leal -4(%ebp), %eax
    > movl %eax, (%esp)
    > call __Z10inlineTestRi ;LINK 1
    > movl $0, %eax
    > --- CODE ---
    >
    > I think that if it worked as you say, LINK 1 would be addl $5, %eax or
    > something like that.


    And where's the produced code that proves that the function gets inlined if
    you remove the pointer?

    > On the other hand, when I get the assembly compiling with -O2, crazy stuff
    > happens and I can't read it.


    Yes. One thing it does with -O2 is enable inlining.
    Rolf Magnus, Mar 22, 2005
    #9
    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. Ronald Fischer
    Replies:
    3
    Views:
    563
    Roedy Green
    Jul 20, 2004
  2. Alex
    Replies:
    6
    Views:
    410
  3. Gianni Mariani

    inlining function objects

    Gianni Mariani, Feb 23, 2004, in forum: C++
    Replies:
    7
    Views:
    378
  4. Replies:
    5
    Views:
    454
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    655
Loading...

Share This Page