Valid code or not?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • WDS

    #1

    Valid code or not?

    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<boo lp;
    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::vec tor<bool, std::allocator< bool' is not
    a member of `std::vector<bo ol, 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
  • Fei Liu

    #2
    Re: Valid code or not?

    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<boo lp;
    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::vec tor<bool, std::allocator< bool' is not
    a member of `std::vector<bo ol, 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

    Comment

    • WDS

      #3
      Re: Valid code or not?

      On Jun 23, 10:24 am, Fei Liu <fei....@gmail. comwrote:
      It's invalid.
      OK, which compiler's explanation (if any) is correct as to why it is
      invalid?

      Comment

      • Ivan Novick

        #4
        Re: Valid code or not?

        On Jun 23, 8:21 am, WDS <B...@seurer.ne twrote:
        void P()
        {
            std::vector<boo lp;
            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.



        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/

        Comment

        • WDS

          #5
          Re: Valid code or not?

          On Jun 23, 12:54 pm, Ivan Novick <i...@novickmai l.comwrote:
          On Jun 23, 8:21 am, WDS <B...@seurer.ne twrote:void P()
          {
              std::vector<boo lp;
              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<boo l*p;
          p->std::~vector<b ool>(); // Line 6

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

          >
          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.

          Comment

          • James Kanze

            #6
            Re: Valid code or not?

            On Jun 23, 5:21 pm, WDS <B...@seurer.ne twrote:
            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<boo lp;
            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<b ool>::~vector<b ool>() 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::vec tor<bool, std::allocator< bool' is not
            a member of `std::vector<bo ol, 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:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            Working...