Re: new foo::foo() erroneous, ugly, or OK?
Greg Herlihy wrote:
Victor Bazarov wrote:
usenet@schweikhardt.net wrote:
gcc accepts the following code, while
FlexeLint 8.00u reports an error:
$ cat foo.cpp
class foo {
public:
foo() { }
};
int main (void)
{
foo *myfoo = new foo::foo();
delete myfoo;
return 0;
}
---snip---
FlexeLint for C/C++ (Unix) Vers. 8.00u, Copyright
Gimpel Software 1985-2006
--- Module: foo.cpp (C++)
foo *myfoo = new foo::foo();
foo.cpp 8 Error 1018: Expected a type after 'new'
[...]
I'm not a C++ expert, so my question to the resident AI
is: Is this in fact an error, or does the C++ standard
allow this syntactically/semantically?
It is perfectly fine. 'foo' _class_ owns the name 'foo' as
its own type. 'foo::foo' is just as good as a *type-id* as,
for example 'foo::foo::foo::foo::foo::foo'. There should be
no error report. FlexeLint is buggy (as much as they love
touting their own horn, thier software is written by people
too).
No, the expression is illegal according to ?3.4.3.1. "The
[interior] name shall represent one or more members of that
class or of one of its base classes". Since "foo" does not
name a member of "foo" or one of its base classes, the
expression is illegal and should not compile.
Precisely. And according to ?9/2, the class name *is* a member
of the class. johnchx2 pointed out correctly that according to
?5.1/7, in an expression (but only in an expression) of the form
class-name::class-name, where both class-name name the same
class, the second is interpreted to be the name of the
constructor, which isn't legal in a new expression.
He also posted a reference to a DR, which in turn referred to
other DR's, which indicate that globally, the situation changed
from C++98 to C++03, and will probably change again in the the
next version. Given the activity on the issue, I think it's
safe to say that generally speaking, even the committee doesn't
know whether this is (or should be) legal.
The expression is almost legal in the latest draft C++
standard - as the name of a constructor.
According to ?12.1/1, constructors don't have names. Of course,
there are other paragraphs which state that name lookup may find
the name of a constructor in some cases:-).
The latest draft definitly allows foo::foo in general. As the
name of the class in contexts where the name of a constructor is
not acceptable (whatever that means).
But as the following example shows, without the "class" or
"struct" keyword, the expression is still an error:
struct A { A(); };
struct B: public A { B(); };
...
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A
The last two are legal in C++98, and according to the latest
draft, but not according to TC1.
Even gcc acknowledges that prefixing the class name is not
standard C++ - but allows it anyway as a harmless redundancy.
The latest version of g++ I have doesn't understand -std=c++03;
all it supports is -std=c++98. In C++98, struct A::A is clearly
allowed.
I don't know what the policy of g++ is on this. Logically, if
they support a -std=c++03, they'd have to ban it there, while
still allowing it in -std=c++98. But when they get around to
-std=c++09 (or whatever it ends up), they'll have to allow it
again.
Personally, if I were writing a compiler, I'd just emit a
warning, in all cases, and document that when conforming to
C++03, that warning is a diagnostic, in the sense of the
standard, but it is not one in the other cases.
Whether one shares that view or not, there is no question that
this syntax is errorneous according to both the current and
forthcoming C++ Standard.
Well, the standards committee doesn't seem to agree with you
there. They keep rehashing the question (and changing the
legality).
--
James Kanze GABI Software
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]