Virtual Functions And Inline Definition

Discussion in 'C++' started by Marcelo De Brito, May 7, 2009.

  1. Hi!

    Why is not possible to define a pure virtual inline function in C++?

    For example:

    class c1 {
    virtual void f() = 0 {} // ERROR
    virtual void g() = 0; // FINE
    };

    Why?

    I appreciate your comments, suggestions, and etc.

    Thank you!

    Marcelo de Brito
     
    Marcelo De Brito, May 7, 2009
    #1
    1. Advertising

  2. Marcelo De Brito wrote:
    > Why is not possible to define a pure virtual inline function in C++?
    >
    > For example:
    >
    > class c1 {
    > virtual void f() = 0 {} // ERROR
    > virtual void g() = 0; // FINE
    > };
    >
    > Why?


    Because the Standard says so (9.2, 10.4/2).

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 7, 2009
    #2
    1. Advertising

  3. Marcelo De Brito

    Phlip Guest

    Marcelo De Brito wrote:
    > Hi!
    >
    > Why is not possible to define a pure virtual inline function in C++?
    >
    > For example:
    >
    > class c1 {
    > virtual void f() = 0 {} // ERROR
    > virtual void g() = 0; // FINE
    > };
    >
    > Why?
    >
    > I appreciate your comments, suggestions, and etc.


    Because a virtual function is secretly a pointer to a function, and {} inside a
    class is the same as an explicit inline. 'inline' is a hint to the compiler it
    can push a method's opcodes into its call sites, without the overhead of calling
    a function and jumping into a different stack frame. Methods defined inside
    classes are 'inline' by default.

    Taking the address of an inline function, in turn, blows away that "hint", and
    forces the function to appear out-of-line. And the compiler must take the
    address to generate the secret pointer for virtual dispatch.

    All these rules were invented when C was young. Pure virtual is a late addition,
    so it does what other abuses of inline cannot - it puts up an error if you
    attempt to mix the virtual and inline concepts together.

    The C++ FAQ will have an answer here too, potentially more accurate!

    --
    Phlip
     
    Phlip, May 7, 2009
    #3
  4. Marcelo De Brito

    Neelesh Guest

    On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    > Hi!
    >
    > Why is not possible to define a pure virtual inline function in C++?
    >


    It is possible (but the 'inline' request will be ignored). The
    following code compiles well.

    class X
    {
    virtual void f() = 0;
    };

    inline void X::f()
    {
    }

    > For example:
    >
    > class c1 {
    >   virtual void f() = 0 {} // ERROR
    >   virtual void g() = 0;    // FINE
    >
    > };
    >


    So what you meant was: Why is it not possible to define a pure virtual
    function inside the class body (or, in other words - why is it not
    possible to give a function declaraction for a pure virtual function
    using "= 0" syntax and also provide a definition there).

    The answer to that question is : "a function declaration cannot
    provide both a pure-specifier
    and a definition" (10.4p2). By "pure-specifier" the c++ standard means
    the syntax "= 0".
     
    Neelesh, May 7, 2009
    #4
  5. Phlip wrote:
    > Marcelo De Brito wrote:
    >> Hi!
    >>
    >> Why is not possible to define a pure virtual inline function in C++?
    >>
    >> For example:
    >>
    >> class c1 {
    >> virtual void f() = 0 {} // ERROR
    >> virtual void g() = 0; // FINE
    >> };
    >>
    >> Why?
    >>
    >> I appreciate your comments, suggestions, and etc.

    >
    > Because a virtual function is secretly a pointer to a function, and {}
    > inside a class is the same as an explicit inline. 'inline' is a hint to
    > the compiler it can push a method's opcodes into its call sites, without
    > the overhead of calling a function and jumping into a different stack
    > frame. Methods defined inside classes are 'inline' by default.


    So? A regular function can be both virtual and inline (defined in the
    class definition).

    > Taking the address of an inline function, in turn, blows away that
    > "hint", and forces the function to appear out-of-line. And the compiler
    > must take the address to generate the secret pointer for virtual dispatch.


    That shouldn't prevent the compiler from being able to substitute the
    body of the function where it can.

    > All these rules


    Which ones? That a virtual function is secretly a pointer to a function?

    > were invented when C was young. Pure virtual is a late
    > addition, so it does what other abuses of inline cannot - it puts up an
    > error if you attempt to mix the virtual and inline concepts together.
    >
    > The C++ FAQ will have an answer here too, potentially more accurate!


    Is that a promise?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 7, 2009
    #5
  6. Marcelo De Brito

    James Kanze Guest

    On May 7, 8:47 pm, Phlip <> wrote:
    > Marcelo De Brito wrote:


    > > Why is not possible to define a pure virtual inline function
    > > in C++?


    > > For example:


    > > class c1 {
    > > virtual void f() = 0 {} // ERROR
    > > virtual void g() = 0; // FINE
    > > };


    > > Why?


    > > I appreciate your comments, suggestions, and etc.


    > Because a virtual function is secretly a pointer to a
    > function,


    Since when?

    > and {} inside a class is the same as an explicit
    > inline. 'inline' is a hint to the compiler it can push a
    > method's opcodes into its call sites, without the overhead of
    > calling a function and jumping into a different stack frame.
    > Methods defined inside classes are 'inline' by default.


    > Taking the address of an inline function, in turn, blows away
    > that "hint", and forces the function to appear out-of-line.


    Since when? Taking the address of a function does require that
    there be a single, out of line instance, but that's true of any
    inline function.

    > And the compiler must take the address to generate the secret
    > pointer for virtual dispatch.


    Perhaps. But what does that have to do with anything. That's
    an implementation detail---the compiler's problem, not yours.

    > All these rules were invented when C was young.


    What rules? When C was young (and even today), it didn't have
    member functions, much less virtual functions. And when C was
    young (until 1999, in fact), it didn't have inline functions.

    > Pure virtual is a late addition,


    Well, it doesn't seem to be in the first edition of TC++PL. But
    it's present in the ARM, and certainly predates templates and
    exceptions.

    > so it does what other abuses of inline cannot - it puts up an
    > error if you attempt to mix the virtual and inline concepts
    > together.


    Have you actually tried. Inline and virtual are orthogonal;
    there's absolutely no problem making a virtual function inline
    (and at least one idiom depends on it).

    The only reason his first example is illegal is because the
    grammar doesn't allow it. Maybe because someone had realized
    that the whole concept of defining a function in the class was
    wrong, and decided not to support it for anything new. But more
    likely simply because no one thought to extend the grammar to
    support it, and afterwards, it wasn't considered important
    enough to bother with.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 8, 2009
    #6
  7. Marcelo De Brito

    James Kanze Guest

    On May 7, 9:04 pm, Neelesh <> wrote:
    > On May 7, 11:36 pm, Marcelo De Brito <> wrote:


    > > Why is not possible to define a pure virtual inline function
    > > in C++?


    > It is possible (but the 'inline' request will be ignored).


    It certainly will not be ignored.

    > The following code compiles well.


    > class X
    > {
    > virtual void f() = 0;
    > };


    > inline void X::f()
    > {
    > }
    > > For example:


    Yes. And if the compiler actually ignored the inline request,
    you couldn't use such a header in more than one translation
    unit.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 8, 2009
    #7
  8. Marcelo De Brito

    Neelesh Guest

    On May 8, 1:59 pm, James Kanze <> wrote:
    > On May 7, 9:04 pm, Neelesh <> wrote:
    >
    > > On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    > > > Why is not possible to define a pure virtual inline function
    > > > in C++?

    > > It is possible (but the 'inline' request will be ignored).

    >
    > It certainly will not be ignored.
    >

    The above inline request can be honored by the compiler only if the
    compiler can prove that this function is never called polymorphically.
    I guess that is extremely difficult.

    > > The following code compiles well.
    > > class X
    > > {
    > >    virtual void f()  = 0;
    > > };
    > > inline void X::f()
    > > {
    > > }
    > > > For example:

    >
    > Yes.  And if the compiler actually ignored the inline request,
    > you couldn't use such a header in more than one translation
    > unit.
    >


    IMHO, even if the compiler actually ignores the inline request, the
    very thing that "we have requested the compiler to make the function
    inline" gives us all the rights of multiple (identical) defintions for
    that function, one per translation unit. Quoting the standard -

    7.1.2/2: A function declaration (8.3.5, 9.3, 11.4) with an inline
    specifier declares an inline function. The inline specifier indicates
    to the implementation that inline substitution of the function body at
    the point of call is to be preferred to the usual function call
    mechanism. An implementation is not required to perform this inline
    substitution at the point of call; however, even if this inline
    substitution is omitted, the other rules forinline functions defined
    by 7.1.2 shall still be respected.

    7.1.2/4: An inline function shall be defined in every translation unit
    in which it is used and shall have exactly the same definition in
    every case

    This means that as long as we specify a function as "inline", we
    should (rather we must) define it in all translation units. Hence
    using such a header in multiple translation units should not be a
    problem.

    Thanks.
     
    Neelesh, May 8, 2009
    #8
  9. * Neelesh:
    > On May 8, 1:59 pm, James Kanze <> wrote:
    >> On May 7, 9:04 pm, Neelesh <> wrote:
    >>
    >>> On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    >>>> Why is not possible to define a pure virtual inline function
    >>>> in C++?
    >>> It is possible (but the 'inline' request will be ignored).

    >> It certainly will not be ignored.
    >>

    > The above inline request can be honored by the compiler only if the
    > compiler can prove that this function is never called polymorphically.
    > I guess that is extremely difficult.


    I'm sorry, the above is meaningless.

    It seems that you have misunderstood what 'inline' is about.

    It has a guaranteed effect and a hinting effect; read up on it.


    Cheers & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, May 8, 2009
    #9
  10. Marcelo De Brito

    Neelesh Guest

    On May 8, 3:12 pm, "Alf P. Steinbach" <> wrote:
    > * Neelesh:
    >
    > > On May 8, 1:59 pm, James Kanze <> wrote:
    > >> On May 7, 9:04 pm, Neelesh <> wrote:

    >
    > >>> On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    > >>>> Why is not possible to define a pure virtual inline function
    > >>>> in C++?
    > >>> It is possible (but the 'inline' request will be ignored).
    > >> It certainly will not be ignored.

    >
    > > The above inline request can be honored by the compiler only if the
    > > compiler can prove that this function is never called polymorphically.
    > > I guess that is extremely difficult.

    >
    > I'm sorry, the above is meaningless.
    >
    > It seems that you have misunderstood what 'inline' is about.
    >
    > It has a guaranteed effect and a hinting effect; read up on it.
    >


    Is "hinting effect" a technical term? I'm sorry I'm not aware of it.
    Did a quick googling but that couldn't help. Also, this term doesn't
    seem appear in the C++ standard

    My _only_ understanding about semantics of "inline" specifier is this:

    -It is a request made to the compiler and the compiler is at its own
    descretion whether to obey this request or not. Of course, it will
    obey if it can.
    - If there are any specific cases where the compiler is "forced" to
    inline, then I am not aware of such cases.
    - I gather that if a function is inlined, _all_ its calls must be
    substituted by its definition. I am not aware if the compilers are
    allowed to selectively replace the calls that it can.

    Would be greatful if you could point to a relevant resource that talks
    about all these, specially the "hinting effect".

    Thanks
    Neelesh
     
    Neelesh, May 8, 2009
    #10
  11. Marcelo De Brito

    Neelesh Guest

    On May 8, 1:58 pm, James Kanze <> wrote:

    > Have you actually tried.  Inline and virtual are orthogonal;
    > there's absolutely no problem making a virtual function inline
    > (and at least one idiom depends on it).
    >


    Can you please throw some more light on this? Specifically which idiom
    and why wouldn't there be any problem? For example, here:

    struct X
    {
    virtual int f() { return 1;}
    };

    struct Y : public X
    {
    int f() { return 2; }
    };

    int main()
    {
    X*x = new Y();
    x->f();
    }

    Will a call to f() in main get inlined? If yes, then how does the
    compiler understand whether to use X::f() or Y::f() ?

    Thanks.
     
    Neelesh, May 8, 2009
    #11
  12. * Neelesh:
    > On May 8, 3:12 pm, "Alf P. Steinbach" <> wrote:
    >> * Neelesh:
    >>
    >>> On May 8, 1:59 pm, James Kanze <> wrote:
    >>>> On May 7, 9:04 pm, Neelesh <> wrote:
    >>>>> On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    >>>>>> Why is not possible to define a pure virtual inline function
    >>>>>> in C++?
    >>>>> It is possible (but the 'inline' request will be ignored).
    >>>> It certainly will not be ignored.
    >>> The above inline request can be honored by the compiler only if the
    >>> compiler can prove that this function is never called polymorphically.
    >>> I guess that is extremely difficult.

    >> I'm sorry, the above is meaningless.
    >>
    >> It seems that you have misunderstood what 'inline' is about.
    >>
    >> It has a guaranteed effect and a hinting effect; read up on it.
    >>

    >
    > Is "hinting effect" a technical term? I'm sorry I'm not aware of it.
    > Did a quick googling but that couldn't help. Also, this term doesn't
    > seem appear in the C++ standard
    >
    > My _only_ understanding about semantics of "inline" specifier is this:
    >
    > -It is a request made to the compiler and the compiler is at its own
    > descretion whether to obey this request or not. Of course, it will
    > obey if it can.
    > - If there are any specific cases where the compiler is "forced" to
    > inline, then I am not aware of such cases.
    > - I gather that if a function is inlined, _all_ its calls must be
    > substituted by its definition. I am not aware if the compilers are
    > allowed to selectively replace the calls that it can.
    >
    > Would be greatful if you could point to a relevant resource that talks
    > about all these, specially the "hinting effect".


    What you describe is the hinting effect.

    The guaranteed effect is to allow multiple in-a-practical-sense-identical
    definitions as long as they're in different compilation units, which as a matter
    of in-practice programming allows you to define routines in header files.

    The guaranteed effect is the only effect that you should be concerned about
    (hinting is only for effeminate politicians, not for engineers), i.e., just
    forget that hinting stuff -- although before forgetting it, note that contrary
    to your description machine code inlining is decided per call, not per routine.


    Cheers & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, May 8, 2009
    #12
  13. Marcelo De Brito

    James Kanze Guest

    On May 8, 11:49 am, Neelesh <> wrote:
    > On May 8, 1:59 pm, James Kanze <> wrote:>
    > On May 7, 9:04 pm, Neelesh <> wrote:


    > > > On May 7, 11:36 pm, Marcelo De Brito <> wrote:
    > > > > Why is not possible to define a pure virtual inline
    > > > > function in C++?
    > > > It is possible (but the 'inline' request will be ignored).


    > > It certainly will not be ignored.


    > The above inline request can be honored by the compiler only
    > if the compiler can prove that this function is never called
    > polymorphically. I guess that is extremely difficult.


    First, the standard requires that the "request" be honored. The
    way the "one definition rule" works is different for inline
    functions and non-inline functions. And this is, strictly
    speaking, the only formal difference. (A good compiler will, of
    course, take the recommended hint into consideration. Unless it
    can do better by ignoring it.) A function declared inline
    *must* be defined in every translation unit it uses; a function
    which in not declared inline must be defined in exactly one
    translation unit, no more, no less. And a compiler which
    ignores is broken, to the point of being unusable. (But I've
    never seen a compiler which ignored it.)

    Second, a function which is declared virtual is always called
    polymorphically---i.e. the actual function called will depend on
    the dynamic type of the object. How the compiler achieves this
    is its business, of course, but typically, all of the compilers
    I know use exactly the same mechanism as for a non-inline
    function anytime they know the dynamic type. Which isn't
    necessarily that rare, depending on how the object is used.

    > > > The following code compiles well.
    > > > class X
    > > > {
    > > > virtual void f() = 0;
    > > > };
    > > > inline void X::f()
    > > > {
    > > > }
    > > > > For example:


    > > Yes. And if the compiler actually ignored the inline
    > > request, you couldn't use such a header in more than one
    > > translation unit.


    > IMHO, even if the compiler actually ignores the inline
    > request, the very thing that "we have requested the compiler
    > to make the function inline" gives us all the rights of
    > multiple (identical) defintions for that function, one per
    > translation unit.


    Yes. That's what the inline declarations requests.

    > Quoting the standard -


    > 7.1.2/2: A function declaration (8.3.5, 9.3, 11.4) with an
    > inline specifier declares an inline function. The inline
    > specifier indicates to the implementation that inline
    > substitution of the function body at the point of call is to
    > be preferred to the usual function call mechanism. An
    > implementation is not required to perform this inline
    > substitution at the point of call; however, even if this
    > inline substitution is omitted, the other rules forinline
    > functions defined by 7.1.2 shall still be respected.


    > 7.1.2/4: An inline function shall be defined in every
    > translation unit in which it is used and shall have exactly
    > the same definition in every case


    > This means that as long as we specify a function as "inline",
    > we should (rather we must) define it in all translation units.
    > Hence using such a header in multiple translation units should
    > not be a problem.


    Yes. And. That's basically what I said: if you declare a
    function inline, the compiler is required to obey that request,
    and allow (or rather require) the definition to be present in
    every translation unit where the function is used.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 8, 2009
    #13
  14. Neelesh wrote:

    > On May 8, 3:12 pm, "Alf P. Steinbach" <> wrote:
    >> * Neelesh:
    >>
    >> > On May 8, 1:59 pm, James Kanze <> wrote:
    >> >> On May 7, 9:04 pm, Neelesh <> wrote:

    >>
    >> >>> On May 7, 11:36 pm, Marcelo De Brito <>
    >> >>> wrote:
    >> >>>> Why is not possible to define a pure virtual inline function
    >> >>>> in C++?
    >> >>> It is possible (but the 'inline' request will be ignored).
    >> >> It certainly will not be ignored.

    >>
    >> > The above inline request can be honored by the compiler only if the
    >> > compiler can prove that this function is never called
    >> > polymorphically. I guess that is extremely difficult.

    >>
    >> I'm sorry, the above is meaningless.
    >>
    >> It seems that you have misunderstood what 'inline' is about.
    >>
    >> It has a guaranteed effect and a hinting effect; read up on it.
    >>

    >
    > Is "hinting effect" a technical term? I'm sorry I'm not aware of it.
    > Did a quick googling but that couldn't help. Also, this term doesn't
    > seem appear in the C++ standard


    It is not a technical term, and it can be translated as "the construct
    has a semantic effect that the compiler may or may not apply to the
    code, at the discretion of the compiler".

    >
    > My _only_ understanding about semantics of "inline" specifier is this:
    >
    > -It is a request made to the compiler and the compiler is at its own
    > descretion whether to obey this request or not. Of course, it will
    > obey if it can.


    Because it is a request that the compiler is not required to honour, it
    is a hint.
    How much effort the compiler puts in honouring this request is a QoI
    (Quality of Implementation) issue. To my knowledge, there are currently
    compilers available that ignore the hints of the inline specifier and
    perform inline expansion for any function call where they think it is an
    advantage, regardless of the presence/absence of an inline specifier for
    the function.

    > - If there are any specific cases where the compiler is "forced" to
    > inline, then I am not aware of such cases.


    You can safely assume there is never a requirement to actually perform
    an inline expansion.

    > - I gather that if a function is inlined, _all_ its calls must be
    > substituted by its definition. I am not aware if the compilers are
    > allowed to selectively replace the calls that it can.


    Yes, a compiler is allowed to decide on a call-by-call basis if the
    function call can be expanded inline or not. If only because a strictly
    conforming program will not be able to tell the difference anyway.

    >
    > Would be greatful if you could point to a relevant resource that talks
    > about all these, specially the "hinting effect".


    You yourself already quoted from the relevant resource: clause 7.1.2

    >
    > Thanks
    > Neelesh


    Bart v Ingen Schenau
    --
    a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
    c.l.c FAQ: http://c-faq.com/
    c.l.c++ FAQ: http://www.parashift.com/c -faq-lite/
     
    Bart van Ingen Schenau, May 8, 2009
    #14
    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. Dave Townsend

    inline virtual functions.

    Dave Townsend, May 21, 2004, in forum: C++
    Replies:
    15
    Views:
    677
    Alf P. Steinbach
    May 22, 2004
  2. Replies:
    3
    Views:
    494
  3. Daniel Vallstrom
    Replies:
    2
    Views:
    2,057
    Kevin Bracey
    Nov 21, 2003
  4. John Goche
    Replies:
    10
    Views:
    798
    Marcus Kwok
    Dec 8, 2006
  5. Rahul
    Replies:
    3
    Views:
    480
    James Kanze
    Feb 28, 2008
Loading...

Share This Page