Topic: function ptr decl/object definition ambiguity?


Author: chip@cybernetics.net (Chip Salzenberg)
Date: 1995/06/15
Raw View
According to kanze@gabi-soft.fr (J. Kanze):
>Chip Salzenberg (chip@cybernetics.net) wrote:
>> You know, I always thought that the canonical workaround was to use
>> the "auto" keyword:
>>
>>       auto B obj(A(i));  // obviously a variable
>
>For global variables and statics as well? :-)

Heh.  Good point.  I guess I just don't use that many global variables.  :-)
--
            Chip Salzenberg, aka <chip@cybernetics.net>
     "And remember to worship at the railroad of your choice."
        -- Mike Nelson, MST3K: "The Amazing Transparent Man"





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/12
Raw View
Chip Salzenberg (chip@cybernetics.net) wrote:
|> According to kanze@gabi-soft.fr (J. Kanze):
|> >The compiler is correct.  The question is: is A(i) a declaration (of a
|> >function parameter) or an expression (being used as the argument of an
|> >initialization.  The rules say that a declaration has precedence.
|> >
|> >I generally avoid the ambiguity by putting the typename in parentheses:
|> >
|> > B obj( (A)( i ) ) ;
|> >

|> You know, I always thought that the canonical workaround was to use
|> the "auto" keyword:

|>       auto B obj(A(i));  // obviously a variable

For global variables and statics as well? :-)
--
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





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/12
Raw View
Jason Merrill (jason@cygnus.com) wrote:
|> >>>>> Chip Salzenberg <chip@cybernetics.net> writes:

|> > According to kanze@gabi-soft.fr (J. Kanze):
|> >> The compiler is correct.  The question is: is A(i) a declaration (of a
|> >> function parameter) or an expression (being used as the argument of an
|> >> initialization.  The rules say that a declaration has precedence.
|> >>
|> >> I generally avoid the ambiguity by putting the typename in parentheses:
|> >>
|> >> B obj( (A)( i ) ) ;
|> >>

|> > You know, I always thought that the canonical workaround was to use
|> > the "auto" keyword:

|> >       auto B obj(A(i));  // obviously a variable

|> I don't know whether that should work or not; I suspect it shouldn't, that
|> the disambiguation must be syntactic (and for such purposes 'auto' is just
|> another storage-class-specifier).

A storage class specifier which, I believe, is illegal for functions.
(But like you, I'm not sure whether this semantic restriction is
actually legal for disambiguation.)

|> I use

|> B obj = B(A(i));

|> myself.

Even when B doesn't have an accessible copy constructor? :-)
--
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





Author: chip@cybernetics.net (Chip Salzenberg)
Date: 1995/06/08
Raw View
According to kanze@gabi-soft.fr (J. Kanze):
>The compiler is correct.  The question is: is A(i) a declaration (of a
>function parameter) or an expression (being used as the argument of an
>initialization.  The rules say that a declaration has precedence.
>
>I generally avoid the ambiguity by putting the typename in parentheses:
>
> B obj( (A)( i ) ) ;
>

You know, I always thought that the canonical workaround was to use
the "auto" keyword:

      auto B obj(A(i));  // obviously a variable

--
            Chip Salzenberg, aka <chip@cybernetics.net>
     "And remember to worship at the railroad of your choice."
        -- Mike Nelson, MST3K: "The Amazing Transparent Man"





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/06/08
Raw View
>>>>> Chip Salzenberg <chip@cybernetics.net> writes:

> According to kanze@gabi-soft.fr (J. Kanze):
>> The compiler is correct.  The question is: is A(i) a declaration (of a
>> function parameter) or an expression (being used as the argument of an
>> initialization.  The rules say that a declaration has precedence.
>>
>> I generally avoid the ambiguity by putting the typename in parentheses:
>>
>> B obj( (A)( i ) ) ;
>>

> You know, I always thought that the canonical workaround was to use
> the "auto" keyword:

>       auto B obj(A(i));  // obviously a variable

I don't know whether that should work or not; I suspect it shouldn't, that
the disambiguation must be syntactic (and for such purposes 'auto' is just
another storage-class-specifier).

I use

B obj = B(A(i));

myself.

Jason





Author: daniels@Starbase.NeoSoft.COM (Brad Daniels)
Date: 1995/06/07
Raw View
In article <3r1ve8$2l7@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
...
>The compiler is correct.  The question is: is A(i) a declaration (of a
>function parameter) or an expression (being used as the argument of an
>initialization.  The rules say that a declaration has precedence.
>
>I generally avoid the ambiguity by putting the typename in parentheses:
>
> B obj( (A)( i ) ) ;
>
>(Parentheses are not allowed in the declaration specifier, so `(A)( i )'
>cannot be a declaration.)

Thanks for the work-around.  I've been working around it by creating
temporaries, which should be equivalent except for object scope, but I
think I may use your approach in the future.

You know, I *still* can't find the relevant text, even though two people
have quoted it to me.  Of course, your explanation does make the expression/
declaration paragraph fit this example better.

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





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/06/06
Raw View
Brad Daniels (daniels@Starbase.NeoSoft.COM) wrote:
|> I just ran into a case where a statement seemed to me quite clearly to be
|> an object definition, but which DEC C++ decided was a function declaration.
|> After some thought, I realized where the ambiguity was, but I couldn't find
|> anything in the CD as to how it should be resolved.  Here's an example:

|> class A {
|> public:
|>     A(int i);
|> };

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

|> void bar(int i)
|> {
|>     B obj(A(i));
|>     obj.foo();
|> }

|> Under DEC C++, the obj.foo() call fails because it thinks that B obj(A(i))
|> is equivalent to B obj(A i), meaning it's a function declaration.  If
|> I'd said B obj(A(random_identifier)), it would unambiguously be a function
|> declaration, but since i is a valid identifier in the scope of the statement,
|> and A(i) is a valid ctor invocation, I expected it to treat the statement as
|> an object definition, since that's certainly the most intuitive approach.
|> The rule for disambiguating expressions and declarations isn't strictly
|> applicable here, since we're disambiguating between a definition and a
|> declaration.  I worked around my problem by creating a temporary, but
|> it seems the original code should have been legal.

|> Has this issue been addressed yet?  Is DEC C++ wrong, right, neither?

The compiler is correct.  The question is: is A(i) a declaration (of a
function parameter) or an expression (being used as the argument of an
initialization.  The rules say that a declaration has precedence.

I generally avoid the ambiguity by putting the typename in parentheses:

 B obj( (A)( i ) ) ;

(Parentheses are not allowed in the declaration specifier, so `(A)( i )'
cannot be a declaration.)
--
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





Author: barmar@nic.near.net (Barry Margolin)
Date: 1995/06/03
Raw View
In article <3qnflf$e7@Starbase.NeoSoft.COM> daniels@Starbase.NeoSoft.COM (Brad Daniels) writes:
>I just ran into a case where a statement seemed to me quite clearly to be
>an object definition, but which DEC C++ decided was a function declaration.
>After some thought, I realized where the ambiguity was, but I couldn't find
>anything in the CD as to how it should be resolved.

See section 8.2, dcl.ambig.res.  It says:

1 The ambiguity arising from the  similarity  between  a  function-style
  cast and a declaration mentioned in _stmt.ambig_ can also occur in the
  context of a declaration.  In that context, it surfaces  as  a  choice
  between  a  function  declaration  with a redundant set of parentheses
  around a parameter name and an object  declaration  with  a  function-
  style cast as the initializer.  Just as for statements, the resolution
  is to consider any construct that could possibly be  a  declaration  a
  declaration.   A declaration can be explicitly disambiguated by a non-
  function-style cast or a = to indicate initialization.
--
Barry Margolin
BBN Planet Corporation, Cambridge, MA
barmar@{bbnplanet.com,near.net,nic.near.net,netcom.com}
Phone (617) 873-3126 - Fax (617) 873-5124





Author: rubenst%occs.nlm.nih.gov (Mike Rubenstein Phoenix Contract)
Date: 1995/06/03
Raw View
Brad Daniels (daniels@Starbase.NeoSoft.COM) wrote:
> I just ran into a case where a statement seemed to me quite clearly to be
> an object definition, but which DEC C++ decided was a function declaration.
> After some thought, I realized where the ambiguity was, but I couldn't find
> anything in the CD as to how it should be resolved.  Here's an example:

> class A {
> public:
>     A(int i);
> };

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

> void bar(int i)
> {
>     B obj(A(i));
>     obj.foo();
> }

> Under DEC C++, the obj.foo() call fails because it thinks that B obj(A(i))
> is equivalent to B obj(A i), meaning it's a function declaration.  If
> I'd said B obj(A(random_identifier)), it would unambiguously be a function
> declaration, but since i is a valid identifier in the scope of the statement,
> and A(i) is a valid ctor invocation, I expected it to treat the statement as
> an object definition, since that's certainly the most intuitive approach.
> The rule for disambiguating expressions and declarations isn't strictly
> applicable here, since we're disambiguating between a definition and a
> declaration.  I worked around my problem by creating a temporary, but
> it seems the original code should have been legal.

> Has this issue been addressed yet?  Is DEC C++ wrong, right, neither?

The compiler is correct.  See draft 8.2:

 The ambiguity arising from the similarity between a function-style
 cast and a declaration mentioned in _stmt.ambig_ can also occur in the
 context of a declaration. In that context, it surfaces as a choice
 between a function declaration with a redundant set of parentheses
 around a parameter name and an object declaration with a function-
 style cast as the initializer. Just as for statements, the resolution
 is to consider any construct that could possibly be a declaration a
 declaration. A declaration can be explicitly disambiguated by a
 non-function-style cast or a = to indicate initialization. [Example:

        struct S {
    S(int);
         };

         void foo(double a)
  {
           S x(int(a));        // function declaration
           S x(int());         // function declaration
           S y((int)a);        // object declaration
           S z = int(a);       // object declaration
         }

This is not new.  It is also discussed in ARM 8.1.1 with the same
resolution.

--
Mike Rubenstein





Author: daniels@Starbase.NeoSoft.COM (Brad Daniels)
Date: 1995/06/02
Raw View
I just ran into a case where a statement seemed to me quite clearly to be
an object definition, but which DEC C++ decided was a function declaration.
After some thought, I realized where the ambiguity was, but I couldn't find
anything in the CD as to how it should be resolved.  Here's an example:

class A {
public:
    A(int i);
};

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

void bar(int i)
{
    B obj(A(i));
    obj.foo();
}

Under DEC C++, the obj.foo() call fails because it thinks that B obj(A(i))
is equivalent to B obj(A i), meaning it's a function declaration.  If
I'd said B obj(A(random_identifier)), it would unambiguously be a function
declaration, but since i is a valid identifier in the scope of the statement,
and A(i) is a valid ctor invocation, I expected it to treat the statement as
an object definition, since that's certainly the most intuitive approach.
The rule for disambiguating expressions and declarations isn't strictly
applicable here, since we're disambiguating between a definition and a
declaration.  I worked around my problem by creating a temporary, but
it seems the original code should have been legal.

Has this issue been addressed yet?  Is DEC C++ wrong, right, neither?

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