Topic: Function/local object decl ambiguity


Author: fwai@armltd.co.uk (Francis Wai)
Date: 1996/08/07
Raw View
daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:

>I feel like this has come up before, but I can't find any record of how
>it was resolved.  In the draft of the standard I have, there is mention of
>a similar ambiguity, but not the exact one I ran into.    Here's the case:

If it is d-or-e ambiguity, then that's exactly the explanation you want.

>class A {
>public:
>    A(const B&);
>};

>class B {
>public:
>    B(const char *);
>};

>class C {
>public:
>    operator const char *();
>};

>void f() {
>    C x;
>    A y(B(x));
>}

Here 'B(x)' can be parsed as an expression _and_ a declaration. The Draft
is clear about this; it favours the declaration. Therefore, 'y' is a function.
If it is an object you want, why not try 'A y = B(x);'?

--Francis
--
e-mail: fwai@armltd.co.uk


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Marco Dalla Gasperina" <marcodg@hp-vcd.vcd.hp.com>
Date: 1996/08/08
Raw View
fwai@armltd.co.uk (Francis Wai) wrote in article
<4u9t4f$hig@sis.armltd.co.uk>...
> daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:
>
class defs deleted...

> >void f() {
> >    C x;
> >    A y(B(x));
> >}
>
> Here 'B(x)' can be parsed as an expression _and_ a declaration. The
> Draft is clear about this; it favours the declaration. Therefore,
> 'y' is a function.  If it is an object you want, why not try
> 'A y = B(x);'?

Call me stupid, but I don't get it... how is 'y' a declaration of a
function?
Isn't y an object of class A constructed with a temporary B object?
There is no type specifier on the (would-be) parameter to y() and since
there is no implicit int, it can't be a declaration.

The only ambiguity I can think of is this:

A y();

Here y is a function returning an A and not an object of type A
constructed with a default constructor.

---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/08/08
Raw View
"Marco Dalla Gasperina" <marcodg@hp-vcd.vcd.hp.com> writes:
>[further attributions lost]
>> >    A y(B(x));
>>
>> Here 'B(x)' can be parsed as an expression _and_ a declaration. The
>> Draft is clear about this; it favours the declaration. Therefore,
>> 'y' is a function.
>
>Call me stupid, but I don't get it... how is 'y' a declaration of a
>function?

It's a function taking a parameter named `x' of type `B' and returning
type `A'.

>There is no type specifier on the (would-be) parameter to y()

Yes, there is, the type specificer is `B'.
The parentheses around the `x' are redundant, but allowed.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jason@cygnus.com (Jason Merrill)
Date: 1996/08/08
Raw View
>>>>> Francis Wai <fwai@armltd.co.uk> writes:

>> A y(B(x));

> Here 'B(x)' can be parsed as an expression _and_ a declaration. The Draft
> is clear about this; it favours the declaration. Therefore, 'y' is a
> function.  If it is an object you want, why not try 'A y = B(x);'?

Or even

  A y ((B(x)));

Jason


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: tony@online.tmx.com.au (Tony Cook)
Date: 1996/08/08
Raw View
Francis Wai (fwai@armltd.co.uk) wrote:
: Here 'B(x)' can be parsed as an expression _and_ a declaration. The Draft
: is clear about this; it favours the declaration. Therefore, 'y' is a function.
: If it is an object you want, why not try 'A y = B(x);'?

What if A doesn't have a copy constructor?

--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/08
Raw View
In article <01bb84b9.27bfd480$9775450f@marcod01> "Marco Dalla Gasperina"
<marcodg@hp-vcd.vcd.hp.com> writes:

|> fwai@armltd.co.uk (Francis Wai) wrote in article
|> <4u9t4f$hig@sis.armltd.co.uk>...
|> > daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:
|> >
|> class defs deleted...

|> > >void f() {
|> > >    C x;
|> > >    A y(B(x));
|> > >}
|> >
|> > Here 'B(x)' can be parsed as an expression _and_ a declaration. The
|> > Draft is clear about this; it favours the declaration. Therefore,
|> > 'y' is a function.  If it is an object you want, why not try
|> > 'A y = B(x);'?

|> Call me stupid, but I don't get it... how is 'y' a declaration of a
|> function?

Because "B(x)" is a declaration of a function parameter.  The
parentheses are optional (and meaningless), but legal.

|> Isn't y an object of class A constructed with a temporary B object?

No, y is a function taking a B as argument, and returning an A.

|> There is no type specifier on the (would-be) parameter to y() and since
|> there is no implicit int, it can't be a declaration.

What is B if it is not a type specifier?
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/08
Raw View
In article <4u9t4f$hig@sis.armltd.co.uk> fwai@armltd.co.uk (Francis Wai)
writes:

|> >void f() {
|> >    C x;
|> >    A y(B(x));
|> >}

|> Here 'B(x)' can be parsed as an expression _and_ a declaration. The Draft
|> is clear about this; it favours the declaration. Therefore, 'y' is a function.
|> If it is an object you want, why not try 'A y = B(x);'?

While that would work in this case, it is not a general solution, since
it requires that A have a copy constructor.

I use:

 A y( (B)( x ) ) ;

which works whenever B has a constructor that takes a single argument
(and no ambiguity is possible in the other cases).  One may have
misgivings about its esthetics, though.  When I posted this solution
before, someone emailed me the alternative:

 A y( (B( x ) ) ;

Putting the entire expression in an extra pair of parentheses also
prevents it from being interpreted as a declaration.  (I accidentally
deleted the email before thanking the person for the idea; if he is
reading this now, please accept my apologies.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: fwai@armltd.co.uk (Francis Wai)
Date: 1996/08/08
Raw View
"Marco Dalla Gasperina" <marcodg@hp-vcd.vcd.hp.com> writes:

>fwai@armltd.co.uk (Francis Wai) wrote in article
><4u9t4f$hig@sis.armltd.co.uk>...
>> daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:
>>
>class defs deleted...
>
>> >void f() {
>> >    C x;
>> >    A y(B(x));
>> >}
>>
>> Here 'B(x)' can be parsed as an expression _and_ a declaration. The
>> Draft is clear about this; it favours the declaration. Therefore,
>> 'y' is a function.  If it is an object you want, why not try
>> 'A y = B(x);'?

>There is no type specifier on the (would-be) parameter to y() and since
>there is no implicit int, it can't be a declaration.

'B(x)' _can_ be parsed as a declaration. It has the form 'T D' where 'T' is
a type and 'D' is a declarator; a direct-declarator in this case.

You can read A.R.M. 8.2, or DWP (Oct-95) 8.3 about this.

--Francis
--
e-mail: fwai@armltd.co.uk
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: daniels@Starbase.NeoSoft.COM (Brad Daniels)
Date: 1996/08/02
Raw View
I feel like this has come up before, but I can't find any record of how
it was resolved.  In the draft of the standard I have, there is mention of
a similar ambiguity, but not the exact one I ran into.    Here's the case:

class A {
public:
    A(const B&);
};

class B {
public:
    B(const char *);
};

class C {
public:
    operator const char *();
};

void f() {
    C x;
    A y(B(x));
}

The question is, is y a local variable of type A initialized with a temporary
of type B, or is it a function declaration declaring a function returning A
and taking an argument of type B.  The draft I have states that "B x();"
would be a function declaration rather than an object definition because
empty parens are not allowed in object definitions, but says nothing about
the above case where it is syntactically ambiguous whether y is an object
or a function.  Microsoft Visual C++ claims it's a function, which is
definitely not what I wanted.  It was also a major pain to figure out that's
what it was doing.  The question is, is this a bug in MSVC++, or is it
just a quality of implementation issue that they should probably warn me
that what I get is not what I might expect?

- Brad
--
Brad Daniels   |  "Let others praise ancient times.
daniels@neosoft.com  |   I am glad I was born in these."
I don't work for NeoSoft, and | - Ovid (43 B.C. - 17 A.D)
don't speak for my employer. |
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/08/05
Raw View
daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:

>
> I feel like this has come up before, but I can't find any record of how
> it was resolved.  In the draft of the standard I have, there is mention of
> a similar ambiguity, but not the exact one I ran into.    Here's the case:
>
> class A {
> public:
>     A(const B&);
> };
>
> class B {
> public:
>     B(const char *);
> };
>
> class C {
> public:
>     operator const char *();
> };
>
> void f() {
>     C x;
>     A y(B(x));
> }
>
> The question is, is y a local variable of type A initialized with a temporary
> of type B, or is it a function declaration declaring a function returning A
> and taking an argument of type B.  The draft I have states that "B x();"
> would be a function declaration rather than an object definition because
> empty parens are not allowed in object definitions, but says nothing about
> the above case where it is syntactically ambiguous whether y is an object
> or a function.  Microsoft Visual C++ claims it's a function, which is
> definitely not what I wanted.  It was also a major pain to figure out that's
> what it was doing.  The question is, is this a bug in MSVC++, or is it
> just a quality of implementation issue that they should probably warn me
> that what I get is not what I might expect?

Certainly not a bug.  The line in question declares y as an implicitly
external function taking a B as parameter, and returning an A.  The
basic rule is: if it can be a declaration, it is.  This rule is applied
even within another declaration; the expression "B(x)" can be
interpreted either as an explicit constructor call, or a declaration of
an x of type B.  Since the statement parses OK otherwise when the
expression is interpreted as a declaration, it is a declaration (of a
function parameter).

Personally, I always write "(B)( x )", with the typename in parentheses
like for a cast, in such cases, precisely to avoid the ambiguity.  The
one disadvantage: this is only legal if the constructor takes exactly
one argument.  I think I would have preferred it if explicit constructor
calls always required the typename in parentheses, but it is too late
for this now.  (Even if the standard only allowed it, I could at least
use the parentheses systematically, rather than having to use different
syntaxes according to the number of arguments.)

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]