public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Is that code valid ?
@ 1997-11-24 23:19 Pal Engstad
  1997-11-25 16:09 ` Lassi A. Tuura
  0 siblings, 1 reply; 7+ messages in thread
From: Pal Engstad @ 1997-11-24 23:19 UTC (permalink / raw)
  To: egcs

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.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is that code valid ?
  1997-11-24 23:19 Is that code valid ? Pal Engstad
@ 1997-11-25 16:09 ` Lassi A. Tuura
  1997-11-25 22:49   ` Pal Engstad
  0 siblings, 1 reply; 7+ messages in thread
From: Lassi A. Tuura @ 1997-11-25 16:09 UTC (permalink / raw)
  To: Pal Engstad; +Cc: egcs

Pal Engstad wrote:
> 
> Lassi Tuura 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:

I believe you are confusing two things.  The name above is a
qualified-id, where the nested-name-specifier nominates a class.  Hence,
the following lookup rules apply:

----
  3.4.3.1  Class members                                    [class.qual]

1 If  the nested-name-specifier of a qualified-id nominates a class, the
  name specified after the nested-name-specifier is  looked  up  in  the
  scope  of the class (_class.member.lookup_).  The name shall represent
  one or more members of that class  or  of  one  of  its  base  classes
  (_class.derived_).  
----

The class name is also found in the scope of the class itself:

----
 9   Classes                                                    [class]

...
2 A  class-name is inserted into the scope in which it is declared imme-
  diately after the class-name is seen.  The class-name is also inserted
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  into  the scope of the class itself.  For purposes of access checking,
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  the inserted class name is treated as if it were a public member name.
  A  class-specifier  is  commonly referred to as a class definition.  A
  class is considered defined after the closing brace of its class-spec-
  ifier  has  been  seen even though its member functions are in general
  not yet defined.
----

Hence, the qualified-id `QDate::QDate::QDate::QDate' should be treated
as `QDate' in a the above context.  Definition of a function with that
name would be a different thing.  I am not sure it would be valid as a
constructor name---in my reading it should be (the first two `QDate's
would just be ignored).  In my interpretation it should, however, be
valid as a type name in a context where a type name is allowed.  Anybody
interpret the standard differently?

Cheers,
//lat
-- 
Lassi.Tuura@cern.ch          There's no sunrise without a night

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is that code valid ?
  1997-11-25 16:09 ` Lassi A. Tuura
@ 1997-11-25 22:49   ` Pal Engstad
  0 siblings, 0 replies; 7+ messages in thread
From: Pal Engstad @ 1997-11-25 22:49 UTC (permalink / raw)
  To: Lassi A. Tuura; +Cc: egcs

Lassi A. Tuura wrote:
> 
> I believe you are confusing two things.  The name above is a
> qualified-id, where the nested-name-specifier nominates a class.  Hence,
> the following lookup rules apply:
[--snip--]

I stand corrected and I thank you for your explaination.

I've checked it and I've noticed that the use of Class::Class(arg0) can 
only be to construct a temporary. It is specified that what is on the
left
of the '(' can only be a simple-type-identifier:

simple-type-specifier:
                  ::opt nested-name-specifieropt type-name
                  char
          	  etc.

And the last Class in this context is obviously a type-name:

type-name:
                  class-name
                  enum-name
                  typedef-name
          
Having said this, I do not understand why the standard explicitely 
says that the constructor does not have a name, for instance in:

12.1  Constructors					[class.ctor]

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

So the question is now: Why is there such a requirement? I hope we are
not missing something obvious.

> Hence, the qualified-id `QDate::QDate::QDate::QDate' should be treated
> as `QDate' in a the above context.  Definition of a function with that
> name would be a different thing.  I am not sure it would be valid as a
> constructor name---in my reading it should be (the first two `QDate's
> would just be ignored).  In my interpretation it should, however, be
> valid as a type name in a context where a type name is allowed.  Anybody
> interpret the standard differently?

I am not sure but I think it is ok. For reference here's the important
descriptions:

  9.3  Member functions                                     [class.mfct]

2 A member function may be defined (_dcl.fct.def_) in its class  defini-
  tion,  in which case it is an inline member function (_dcl.fct.spec_),
  or it may be defined outside of its class definition if it has already
  been declared but not defined in its class definition.  A member func-
                                                          ^^^^^^^^^^^^^^
  tion definition that appears outside of  the  class  definition  shall
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  appear  in  a  namespace scope enclosing the class definition.  Except
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  for member function definitions that appear outside of a class defini-
  tion, and except for explicit specializations of template member func-
  tions (_temp.spec_) appearing outside of the class definition, a  mem-
  ber function shall not be redeclared.

5 If the definition of a member function is lexically outside its  class
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  definition,  the  member function name shall be qualified by its class
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  name using the :: operator.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since the definition of the constructor _is_ a member function, the 
name has to be Class::Class(). Since the definition has to be in the 
namescope enclosing the class definition, putting a namespace in front 
of this would not make sense. If 

	Class::Class::Class() {} 

is legal is however not so clear, but I agree. Since this is outside 
the class' namespace and the class-name has put in the namespace's 
scope, I would assume that 
	Class::Class::Class() {}
	       ^
at this point, we are in the class' name scope. Also, since the class 
name is also put into the scope of the class itself, the next 
'Class::' is a scope resolution to itself and in the end specifying 
the constructor.

But is that really what is intended with "shall be qualified by its
class
name using the :: operator" in 9.3.5?

If anyone have access to the final standard I'd appreciate if anyone
can comment on this. Has there been changes?

PKE.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is that code valid ?
       [not found] <347A6CE0.82CCAA81.cygnus.egcs@hunt.inmet.com>
@ 1997-11-25 11:44 ` Jason Merrill
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 1997-11-25 11:44 UTC (permalink / raw)
  To: Pal Engstad, egcs

>>>>> Pal Engstad <engstad@hunt.inmet.com> writes:

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

No, Lassi is correct.  He was referring to

  9   Classes                                                    [class]

2 A  class-name is inserted into the scope in which it is declared imme-
  diately after the class-name is seen.  The class-name is also inserted
  into  the scope of the class itself.

Therefore, QDate::QDate refers to QDate.

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Is that code valid ?
  1997-11-10 21:51 Olivier Galibert
  1997-11-11  1:42 ` Lassi A. Tuura
@ 1997-11-11  5:30 ` Gabriel Dos Reis
  1 sibling, 0 replies; 7+ messages in thread
From: Gabriel Dos Reis @ 1997-11-11  5:30 UTC (permalink / raw)
  To: Olivier Galibert; +Cc: egcs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1001 bytes --]

>>>>> «Olivier», Olivier Galibert <Olivier.Galibert@mines.u-nancy.fr> wrote:

Olivier> I'm not sure whether this should compile or not:
Olivier> QDate KfindTabDialog::string2Date(QString str)
Olivier>   {
Olivier>     int year,month,day;

Olivier>     sscanf(str,"%2d/%2d/%4d",&day,&month,&year);
Olivier>     if (QDate::isValid(year,month,day))
Olivier>         return(QDate(year,month,day));
Olivier>       else
Olivier>         return(QDate::QDate());
Olivier>   };        


Olivier> I'm actually getting:
Olivier> kftabdlg.cpp: In method `class QDate KfindTabDialog::string2Date(class QString)':
Olivier> kftabdlg.cpp:549: parse error before `;'
Olivier> kftabdlg.cpp:550: confused by earlier errors, bailing out

Olivier> Line 549 is "return(QDate::QDate());"


Olivier> Changing that line to "return QDate();" works perfectly though.

	I'am not sure this is the right place to learn C++. Anyway, if
you're intending to get an objet of class Class, you just need to say
Class(). 

-- Gaby

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is that code valid ?
  1997-11-10 21:51 Olivier Galibert
@ 1997-11-11  1:42 ` Lassi A. Tuura
  1997-11-11  5:30 ` Gabriel Dos Reis
  1 sibling, 0 replies; 7+ messages in thread
From: Lassi A. Tuura @ 1997-11-11  1:42 UTC (permalink / raw)
  To: Olivier Galibert; +Cc: egcs

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 ());

Cheers,
//lat
-- 
Lassi.Tuura@cern.ch          There's no sunrise without a night

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Is that code valid ?
@ 1997-11-10 21:51 Olivier Galibert
  1997-11-11  1:42 ` Lassi A. Tuura
  1997-11-11  5:30 ` Gabriel Dos Reis
  0 siblings, 2 replies; 7+ messages in thread
From: Olivier Galibert @ 1997-11-10 21:51 UTC (permalink / raw)
  To: egcs

I'm not sure whether this should compile or not:
QDate KfindTabDialog::string2Date(QString str)
  {
    int year,month,day;

    sscanf(str,"%2d/%2d/%4d",&day,&month,&year);
    if (QDate::isValid(year,month,day))
        return(QDate(year,month,day));
      else
        return(QDate::QDate());
  };        


I'm actually getting:
kftabdlg.cpp: In method `class QDate KfindTabDialog::string2Date(class QString)':
kftabdlg.cpp:549: parse error before `;'
kftabdlg.cpp:550: confused by earlier errors, bailing out

Line 549 is "return(QDate::QDate());"


Changing that line to "return QDate();" works perfectly though.

  OG.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~1997-11-25 22:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-11-24 23:19 Is that code valid ? Pal Engstad
1997-11-25 16:09 ` Lassi A. Tuura
1997-11-25 22:49   ` Pal Engstad
     [not found] <347A6CE0.82CCAA81.cygnus.egcs@hunt.inmet.com>
1997-11-25 11:44 ` Jason Merrill
  -- strict thread matches above, loose matches on Subject: below --
1997-11-10 21:51 Olivier Galibert
1997-11-11  1:42 ` Lassi A. Tuura
1997-11-11  5:30 ` Gabriel Dos Reis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).