This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Is that code valid ?
- To: egcs at cygnus dot com
- Subject: Re: Is that code valid ?
- From: Pal Engstad <engstad at hunt dot inmet dot com>
- Date: Mon, 24 Nov 1997 22:14:56 -0800
Lassi Tuuren wrote:
>
> Olivier Galibert wrote:
> > kftabdlg.cpp:549: parse error before `;'
> > Line 549 is "return(QDate::QDate());"
> >
> > Changing that line to "return QDate();" works perfectly though.
>
> That is valid code, since the class name is found in its own scope.
> Hence, one should be able to repeat `QDate::' arbitrary many times. > In
> other words, assuming the proper declarations, the following is
> perfectly valid, albeit weird code:
>
> return (QDate::QDate::QDate::QDate ());
Please, do not write things out of thin air in this forum.
Note that the constructor of a class has no name:
------------------------------------------------------------------------
12.1 Constructors [class.ctor]
1 Constructors do not have names. A special declarator syntax using an
optional function-specifier (_dcl.fct.spec_) followed by the construc-
tor's class name followed by a parameter list is used to declare or
define the constructor. In such a declaration, optional parentheses
around the constructor class name are ignored. [Example:
class C {
public:
C(); // declares the constructor
};
C::C() { } // defines the constructor
--end example]
2 A constructor is used to initialize objects of its class type.
Because constructors do not have names, they are never found during
name lookup; however an explicit type conversion using the functional
notation (_expr.type.conv_) will cause a constructor to be called to
initialize an object. [Note: for initialization of objects of class
type see _class.init_. ]
------------------------------------------------------------------------
The way the code works is through the _expr.type.conv_ mechanism which
states:
------------------------------------------------------------------------
5.2.3 Explicit type conversion (functional [expr.type.conv]
notation)
1 A simple-type-specifier (_dcl.type_) followed by a parenthesized
expression-list constructs a value of the specified type given the
expression list. If the expression list is a single expression, the
type conversion expression is equivalent (in definedness, and if
defined in meaning) to the corresponding cast expression
(_expr.cast_). If the simple-type-specifier specifies a class type,
the class type shall be complete. If the expression list specifies
more than a single value, the type shall be a class with a suitably
declared constructor (_dcl.init_, _class.ctor_), and the expression
T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2,
...); for some invented temporary variable t, with the result being
the value of t as an rvalue.
2 The expression T(), where T is a simple-type-specifier (_dcl.type.sim-
ple_) for a non-array complete object type or the (possibly cv-quali-
fied) void type, creates an rvalue of the specified type, whose value
is determined by default-initialization (_dcl.init_). [Note: if T is
a non-class type that is cv-qualified, the cv-qualifiers are ignored
when determining the type of the resulting rvalue (_basic.lval_). ]
------------------------------------------------------------------------
So, when you write:
return Class(1, 2, 3);
You are creating a temporary with the result being an rvalue. However,
you can not use the syntax 'Class::Class(1, 2, 3)' since the last
'Class'
is _not_ a name. The only valid identifers after :: are:
unqualified-id:
identifier
operator-function-id
conversion-function-id
~ class-name
template-id
As you can see, the syntax '~ class-name' is allowed. 'class-name' is
not.
The short version of the story is:
1. You can not "call" a constructor.
2. You can however create a temporary object (and by this call
the constructor) by the construct
Class(param1, param2, ...);
3. You can call the destructor, for instance by:
this->~Class();
Having said this, I haven't figured out if you may use the name-space
qualifier in constructing a temporary object:
NameSpace::Class(1, 2, 3);
Any takers?
PKE.