Valid code or not?

Discussion in 'C++' started by WDS, Jun 23, 2008.

  1. WDS

    WDS Guest

    I was compiling some old code with a new compiler and it flagged a
    statement as an error. This code compiled (and ran) fine with an
    older version of the same compiler. The following snippet
    demonstrates:

    #include <vector>

    void P()
    {
    std::vector<bool> p;
    p.std::~vector<bool>(); // Line 6
    }

    It that actually valid code? I tried the snippet with various
    compilers and here's what I found:

    #1: gCC

    gCC 3.3.2 accepts it but 3.4.5 complains:

    t.C: In function `void P()':
    t.C:6: error: `std::~std::vector<bool, std::allocator<bool> >' is not
    a member of `std::vector<bool, std::allocator<bool> >'

    #2: xlC

    AIX xlC older versions accept it but the latest version complains:

    "t.C", line 6.24: CZP0157(30) The text ">" is unexpected. It may be
    that this token was intended as a template argument list terminator
    but the name is not known to be a template.

    #3: Visual C++

    Both Microsoft Visual 2005 and 2008 C++ complain:

    t.cpp(6) : error C2588: '::~vector' : illegal global destructor
     
    WDS, Jun 23, 2008
    #1
    1. Advertising

  2. WDS

    Fei Liu Guest

    WDS wrote:
    > I was compiling some old code with a new compiler and it flagged a
    > statement as an error. This code compiled (and ran) fine with an
    > older version of the same compiler. The following snippet
    > demonstrates:
    >
    > #include <vector>
    >
    > void P()
    > {
    > std::vector<bool> p;
    > p.std::~vector<bool>(); // Line 6
    > }
    >
    > It that actually valid code? I tried the snippet with various
    > compilers and here's what I found:
    >
    > #1: gCC
    >
    > gCC 3.3.2 accepts it but 3.4.5 complains:
    >
    > t.C: In function `void P()':
    > t.C:6: error: `std::~std::vector<bool, std::allocator<bool> >' is not
    > a member of `std::vector<bool, std::allocator<bool> >'
    >
    > #2: xlC
    >
    > AIX xlC older versions accept it but the latest version complains:
    >
    > "t.C", line 6.24: CZP0157(30) The text ">" is unexpected. It may be
    > that this token was intended as a template argument list terminator
    > but the name is not known to be a template.
    >
    > #3: Visual C++
    >
    > Both Microsoft Visual 2005 and 2008 C++ complain:
    >
    > t.cpp(6) : error C2588: '::~vector' : illegal global destructor


    It's invalid.

    F
     
    Fei Liu, Jun 23, 2008
    #2
    1. Advertising

  3. WDS

    WDS Guest

    On Jun 23, 10:24 am, Fei Liu <> wrote:
    > It's invalid.


    OK, which compiler's explanation (if any) is correct as to why it is
    invalid?
     
    WDS, Jun 23, 2008
    #3
  4. WDS

    Ivan Novick Guest

    On Jun 23, 8:21 am, WDS <> wrote:
    > void P()
    > {
    >     std::vector<bool> p;
    >     p.std::~vector<bool>();  // Line 6
    >
    > }
    >

    Regardless of your compilation i think your destructor will get called
    2 times and your code will be undefined.

    http://www.parashift.com/c -faq-lite/dtors.html#faq-11.5

    By the way, do you really need the std qualification on Line 6. It
    seems to compile on gcc 4.x if you remove the std qualification there.

    Ivan Novick
    http://www.mycppquiz.com/
     
    Ivan Novick, Jun 23, 2008
    #4
  5. WDS

    WDS Guest

    On Jun 23, 12:54 pm, Ivan Novick <> wrote:
    > On Jun 23, 8:21 am, WDS <> wrote:> void P()
    > > {
    > >     std::vector<bool> p;
    > >     p.std::~vector<bool>();  // Line 6

    >
    > > }

    >
    > Regardless of your compilation i think your destructor will get called
    > 2 times and your code will be undefined.


    Actually, the original code has pointers, kind of like this:

    std::vector<bool> *p;
    p->std::~vector<bool>(); // Line 6

    I was playing around with it and had switched to the non-pointer
    version just before posting.

    > http://www.parashift.com/c -faq-lite/dtors.html#faq-11.5
    >
    > By the way, do you really need the std qualification on Line 6.  It
    > seems to compile on gcc 4.x if you remove the std qualification there.


    Dunno. It was there and worked OK before I switched compilers.
     
    WDS, Jun 23, 2008
    #5
  6. WDS

    James Kanze Guest

    On Jun 23, 5:21 pm, WDS <> wrote:
    > I was compiling some old code with a new compiler and it
    > flagged a statement as an error. This code compiled (and ran)
    > fine with an older version of the same compiler. The
    > following snippet demonstrates:


    > #include <vector>


    > void P()
    > {
    > std::vector<bool> p;
    > p.std::~vector<bool>(); // Line 6
    > }


    > It that actually valid code?


    I can't tell, reading the standard. What's interesting is that
    given:

    namespace N {
    enum E { a, b, c } ;
    class C {} ;
    }

    int
    main()
    {
    N::E e ;
    N::C c ;
    e.N::~E() ;
    c.N::~C() ;
    }

    g++ (4.1.0) accepts the first destructor call, but not the
    second. In your example, both
    p.std::vector<bool>::~vector<bool>() and p.~vector<bool>() work,
    but qualifying with the namespace, but not the class name,
    doesn't.

    This is covered in several different places in the standard, and
    it seems possible as irrational as it seems, this behavior from
    g++ is what the standard requires. The standard seems to
    distinguish between "pseudo destructor calls" (§5.2.4, for
    non-class types) and "explicit destructor calls" (§12.4/11, for
    class types). I can't find any grammar productions for the
    latter, however. All of the examples under consideration
    correspond to the grammar for a pseudo destructor call, but
    §5.2.4 seem to imply that there is a semantic restriction on
    this production, and that it can only be used if the type name
    is not a class type. I would have imagined that the intent was
    (or should have been) that the grammar for both explicit
    destructor calls and pseudo destructor calls be the same, and
    that only the semantics depend on whether the object is a class
    type or not. (Another interesting question is if the type name
    is an array of class types---an array is not a class type, even
    if its elements are, and §5.2.4 would seem to say that the
    following is legal:

    class C { public : ~C() ; } ;
    typedef C A[5] ;

    int main()
    {
    A a ;
    a.~A() ;
    }

    but that the "pseudo destructor call" doesn't actually call any
    destructors.)

    > I tried the snippet with various compilers and here's what I
    > found:


    > #1: gCC


    > gCC 3.3.2 accepts it but 3.4.5 complains:


    > t.C: In function `void P()':
    > t.C:6: error: `std::~std::vector<bool, std::allocator<bool> >' is not
    > a member of `std::vector<bool, std::allocator<bool> >'


    > #2: xlC


    > AIX xlC older versions accept it but the latest version complains:


    > "t.C", line 6.24: CZP0157(30) The text ">" is unexpected. It
    > may be that this token was intended as a template argument
    > list terminator but the name is not known to be a template.


    > #3: Visual C++


    > Both Microsoft Visual 2005 and 2008 C++ complain:


    > t.cpp(6) : error C2588: '::~vector' : illegal global destructor


    Given the ambiguities in the standard, I'm not too surprised
    that compilers differ, although from what you say, the evolution
    seems to be in the same direction. You can always drop all
    namespace qualifications for a class type; the fact that the
    type to the left of the . or the -> is a class type conditions
    name lookup in such a way that the code will work. If the code
    is in a template, however, and you don't know whether the type
    is a class type or not, you may have a problem. (On the other
    hand, I can't think of a case where you wouldn't know except
    when the type is an instantiation type of the template. And you
    don't want a namespace qualifier there.)

    --
    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, Jun 24, 2008
    #6
    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. Jen
    Replies:
    2
    Views:
    5,159
    mehrbod
    Feb 18, 2010
  2. =?Utf-8?B?SlJPQ2FtYXJv?=
    Replies:
    6
    Views:
    4,188
  3. Baski
    Replies:
    2
    Views:
    3,277
    bruce barker
    Dec 21, 2004
  4. Replies:
    64
    Views:
    1,254
    Dave Thompson
    Dec 20, 2004
  5. Any C code are valid C++ code?

    , Dec 10, 2004, in forum: C Programming
    Replies:
    67
    Views:
    1,170
    Dave Thompson
    Dec 20, 2004
Loading...

Share This Page