Valid code or not?

W

WDS

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
 
F

Fei Liu

WDS said:
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
 
W

WDS

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

James Kanze

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:
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> >'
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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top