What's the standard say about this code?

Discussion in 'C++' started by Daniel T., Sep 30, 2008.

  1. Daniel T.

    Daniel T. Guest

    #include <cassert>

    class Foo {
    public:
    virtual void fnA() = 0;
    virtual void fnB() = 0;
    };

    int main() {
    assert( &Foo::fnB );
    assert( &Foo::fnA );
    }

    What does the standard say about the above code? In the compiler I'm
    using now, the first assert will not fire, but the second one will. I
    expected that neither assert would fire...
    Daniel T., Sep 30, 2008
    #1
    1. Advertising

  2. On Sep 30, 4:40 pm, "Daniel T." <> wrote:
    > #include <cassert>
    >
    > class Foo {
    > public:
    >         virtual void fnA() = 0;
    >         virtual void fnB() = 0;
    >
    > };
    >
    > int main() {
    >         assert( &Foo::fnB );
    >         assert( &Foo::fnA );
    >
    > }
    >
    > What does the standard say about the above code? In the compiler I'm
    > using now, the first assert will not fire, but the second one will. I
    > expected that neither assert would fire...


    Are you sure that the second assert is failing?

    Both &Foo::fnB and &Foo::fnA should yield a non-NULL member function
    pointer, which gets converted to bool(true) when passed into assert().

    --
    Max
    Maxim Yegorushkin, Sep 30, 2008
    #2
    1. Advertising

  3. Daniel T.

    Daniel T. Guest

    On Sep 30, 11:53 am, Maxim Yegorushkin <>
    wrote:
    > On Sep 30, 4:40 pm, "Daniel T." <> wrote:
    >
    >
    >
    > > #include <cassert>

    >
    > > class Foo {
    > > public:
    > >         virtual void fnA() = 0;
    > >         virtual void fnB() = 0;

    >
    > > };

    >
    > > int main() {
    > >         assert( &Foo::fnB );
    > >         assert( &Foo::fnA );

    >
    > > }

    >
    > > What does the standard say about the above code? In the compiler I'm
    > > using now, the first assert will not fire, but the second one will. I
    > > expected that neither assert would fire...

    >
    > Are you sure that the second assert is failing?
    >
    > Both &Foo::fnB and &Foo::fnA should yield a non-NULL member function
    > pointer, which gets converted to bool(true) when passed into assert().


    Yes, I am sure that the second assert is failing. If this is a
    compiler bug, then I will submit it to the vendor, but I want to make
    sure it actually *is* a compiler bug first.
    Daniel T., Sep 30, 2008
    #3
  4. Daniel T.

    James Kanze Guest

    On Sep 30, 5:40 pm, "Daniel T." <> wrote:
    > #include <cassert>


    > class Foo {
    > public:
    > virtual void fnA() = 0;
    > virtual void fnB() = 0;
    > };


    > int main() {
    > assert( &Foo::fnB );
    > assert( &Foo::fnA );
    > }


    > What does the standard say about the above code?


    There should be no problem with it.

    > In the compiler I'm using now, the first assert will not fire,
    > but the second one will. I expected that neither assert would
    > fire...


    It's guaranteed by the standard. It works with the three
    compilers I have access to (Sun CC, g++ and VC++), at least when
    you compile in standard conformant mode. (Note that by default,
    pointers to member functions do not work in VC++. You must use
    the option /vmg. Not that I think that their non-conformity
    otherwise would play a role here.)

    --
    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, Oct 1, 2008
    #4
  5. Daniel T.

    Triple-DES Guest

    On 1 Okt, 12:50, "Daniel T." <> wrote:
    > James Kanze <> wrote:
    > > "Daniel T." <> wrote:
    > > > #include <cassert>

    >
    > > > class Foo {
    > > > public:
    > > >         virtual void fnA() = 0;
    > > >         virtual void fnB() = 0;
    > > > };

    >
    > > > int main() {
    > > >         assert( &Foo::fnB );
    > > >         assert( &Foo::fnA );
    > > > }

    >
    > > > What does the standard say about the above code?

    >
    > > There should be no problem with it.

    >
    > > > In the compiler I'm using now, the first assert will not fire,
    > > > but the second one will. I expected that neither assert would
    > > > fire...

    >
    > > It's guaranteed by the standard.  It works with the three
    > > compilers I have access to (Sun CC, g++ and VC++), at least when
    > > you compile in standard conformant mode.  (Note that by default,
    > > pointers to member functions do not work in VC++.  You must use
    > > the option /vmg.  Not that I think that their non-conformity
    > > otherwise would play a role here.)

    >
    > Can I get chapter and verse from the standard on this? It sounds like I
    > need to submit a bug report to the compiler vender.


    I believe it is disallowed by 4.11/1 [conv.mem]:

    "A null pointer constant (4.10) can be converted to a pointer to
    member type; the result is the null member pointer value of that type
    and is distinguishable from any pointer to member not created from a
    null pointer constant.(...)"

    Therefore, an rvalue obtained by using address-of on a member shall
    not yield a null pointer constant.

    > (For those who may be interested in tracking these things, I'm using
    > CodeWarrior  Development Studio for NintendoDS)
    Triple-DES, Oct 1, 2008
    #5
  6. On Oct 1, 12:49 pm, Triple-DES <> wrote:
    > On 1 Okt, 12:50, "Daniel T." <> wrote:
    >
    >
    >
    > > James Kanze <> wrote:
    > > > "Daniel T." <> wrote:
    > > > > #include <cassert>

    >
    > > > > class Foo {
    > > > > public:
    > > > >         virtual void fnA() = 0;
    > > > >         virtual void fnB() = 0;
    > > > > };

    >
    > > > > int main() {
    > > > >         assert( &Foo::fnB );
    > > > >         assert( &Foo::fnA );
    > > > > }

    >
    > > > > What does the standard say about the above code?

    >
    > > > There should be no problem with it.

    >
    > > > > In the compiler I'm using now, the first assert will not fire,
    > > > > but the second one will. I expected that neither assert would
    > > > > fire...

    >
    > > > It's guaranteed by the standard.  It works with the three
    > > > compilers I have access to (Sun CC, g++ and VC++), at least when
    > > > you compile in standard conformant mode.  (Note that by default,
    > > > pointers to member functions do not work in VC++.  You must use
    > > > the option /vmg.  Not that I think that their non-conformity
    > > > otherwise would play a role here.)

    >
    > > Can I get chapter and verse from the standard on this? It sounds like I
    > > need to submit a bug report to the compiler vender.

    >
    > I believe it is disallowed by 4.11/1 [conv.mem]:
    >
    > "A null pointer constant (4.10) can be converted to a pointer to
    > member type; the result is the null member pointer value of that type
    > and is distinguishable from any pointer to member not created from a
    > null pointer constant.(...)"
    >
    > Therefore, an rvalue obtained by using address-of on a member shall
    > not yield a null pointer constant.


    In the original question a member function pointer gets converted to
    bool. Is 4.11/1 applicable here?

    --
    Max
    Maxim Yegorushkin, Oct 1, 2008
    #6
  7. On 2008-10-01 17:11, Maxim Yegorushkin wrote:
    > On Oct 1, 12:49 pm, Triple-DES <> wrote:
    >> On 1 Okt, 12:50, "Daniel T." <> wrote:
    >>
    >>
    >>
    >> > James Kanze <> wrote:
    >> > > "Daniel T." <> wrote:
    >> > > > #include <cassert>

    >>
    >> > > > class Foo {
    >> > > > public:
    >> > > > virtual void fnA() = 0;
    >> > > > virtual void fnB() = 0;
    >> > > > };

    >>
    >> > > > int main() {
    >> > > > assert( &Foo::fnB );
    >> > > > assert( &Foo::fnA );
    >> > > > }

    >>
    >> > > > What does the standard say about the above code?

    >>
    >> > > There should be no problem with it.

    >>
    >> > > > In the compiler I'm using now, the first assert will not fire,
    >> > > > but the second one will. I expected that neither assert would
    >> > > > fire...

    >>
    >> > > It's guaranteed by the standard. It works with the three
    >> > > compilers I have access to (Sun CC, g++ and VC++), at least when
    >> > > you compile in standard conformant mode. (Note that by default,
    >> > > pointers to member functions do not work in VC++. You must use
    >> > > the option /vmg. Not that I think that their non-conformity
    >> > > otherwise would play a role here.)

    >>
    >> > Can I get chapter and verse from the standard on this? It sounds like I
    >> > need to submit a bug report to the compiler vender.

    >>
    >> I believe it is disallowed by 4.11/1 [conv.mem]:
    >>
    >> "A null pointer constant (4.10) can be converted to a pointer to
    >> member type; the result is the null member pointer value of that type
    >> and is distinguishable from any pointer to member not created from a
    >> null pointer constant.(...)"
    >>
    >> Therefore, an rvalue obtained by using address-of on a member shall
    >> not yield a null pointer constant.

    >
    > In the original question a member function pointer gets converted to
    > bool. Is 4.11/1 applicable here?


    No, 4.12 is probably the correct section:

    "An rvalue of arithmetic, enumeration, pointer, or pointer to member
    type can be converted to an rvalue of type bool. A zero value, null
    pointer value, or null member pointer value is converted to false; any
    other value is converted to true."

    --
    Erik Wikström
    Erik Wikström, Oct 1, 2008
    #7
  8. Daniel T.

    Triple-DES Guest

    On 1 Okt, 19:14, Erik Wikström <> wrote:
    > On 2008-10-01 17:11, Maxim Yegorushkin wrote:
    >
    >
    >
    >
    >
    > > On Oct 1, 12:49 pm, Triple-DES <> wrote:
    > >> On 1 Okt, 12:50, "Daniel T." <> wrote:

    >
    > >> > James Kanze <> wrote:
    > >> > > "Daniel T." <> wrote:
    > >> > > > #include <cassert>

    >
    > >> > > > class Foo {
    > >> > > > public:
    > >> > > >         virtual void fnA() = 0;
    > >> > > >         virtual void fnB() = 0;
    > >> > > > };

    >
    > >> > > > int main() {
    > >> > > >         assert( &Foo::fnB );
    > >> > > >         assert( &Foo::fnA );
    > >> > > > }

    >
    > >> > > > What does the standard say about the above code?

    >
    > >> > > There should be no problem with it.

    >
    > >> > > > In the compiler I'm using now, the first assert will not fire,
    > >> > > > but the second one will. I expected that neither assert would
    > >> > > > fire...

    >
    > >> > > It's guaranteed by the standard.  It works with the three
    > >> > > compilers I have access to (Sun CC, g++ and VC++), at least when
    > >> > > you compile in standard conformant mode.  (Note that by default,
    > >> > > pointers to member functions do not work in VC++.  You must use
    > >> > > the option /vmg.  Not that I think that their non-conformity
    > >> > > otherwise would play a role here.)

    >
    > >> > Can I get chapter and verse from the standard on this? It sounds like I
    > >> > need to submit a bug report to the compiler vender.

    >
    > >> I believe it is disallowed by 4.11/1 [conv.mem]:

    >
    > >> "A null pointer constant (4.10) can be converted to a pointer to
    > >> member type; the result is the null member pointer value of that type
    > >> and is distinguishable from any pointer to member not created from a
    > >> null pointer constant.(...)"

    >
    > >> Therefore, an rvalue obtained by using address-of on a member shall
    > >> not yield a null pointer constant.

    >
    > > In the original question a member function pointer gets converted to
    > > bool. Is 4.11/1 applicable here?

    >
    > No, 4.12 is probably the correct section:
    >
    > "An rvalue of arithmetic, enumeration, pointer, or pointer to member
    > type can be converted to an rvalue of type bool. A zero value, null
    > pointer value, or null member pointer value is converted to false; any
    > other value is converted to true."
    >


    Of course, but the problem is that taking the address of a function
    yields a null member pointer value, not the fact that it is
    subsequently converted to false. The OP might as well have written:

    assert( &Foo::fnB != 0);
    assert( &Foo::fnA != 0);

    And 4.12 would be completely irrelevant, but the result of the second
    assert would still violate 4.11/1

    DP
    Triple-DES, Oct 2, 2008
    #8
    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 Rahardja
    Replies:
    5
    Views:
    1,093
    John Harrison
    Jul 18, 2003
  2. Xenos
    Replies:
    1
    Views:
    314
    Rob Williscroft
    Jul 10, 2004
  3. Tobias Oed
    Replies:
    11
    Views:
    1,137
    Dan Pop
    Jun 30, 2003
  4. Sten Westerback

    Re: What does the standard say?

    Sten Westerback, Apr 2, 2004, in forum: C Programming
    Replies:
    3
    Views:
    411
    Rob Thorpe
    Apr 6, 2004
  5. Evan
    Replies:
    0
    Views:
    207
Loading...

Share This Page