Topic: Prototype vs. constructor


Author: "Jim Barry" <jim.barry@bigfoot.com>
Date: 1998/06/15
Raw View
Christopher Eltschka wrote in message
<358127AB.B2471F29@physik.tu-muenchen.de>...
>In C++, you don't need to return a value from main. If you fall
>off the end of main, the result is an implicit return 0;

You're quite right. VC5 warns if you don't return, though.
Interestingly, it also lets you define main as returning void - I
wonder if they'll leave that in for the next version? ;-)

- Jim
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/06/12
Raw View
Jim Barry wrote:
>
> Marco Dalla Gasperina wrote in message
> <6l6boi$pc9@hpbab.wv.mentorg.com>...
> >struct Foo {
> >    void operator() { std::cout << "in operator()" << std::endl; }
> >};
>
> Presumably you meant "operator()()".
>
> >int main()
> >{
> >    Foo    foo();
> >    foo();
> >}
>
> "Foo foo()" is declaration of the function that follows. You forgot to
> return a value from "main".

In C++, you don't need to return a value from main. If you fall
off the end of main, the result is an implicit return 0;

>
> >// then somewhere exists this definition
> >Foo foo()
> >{
> >    std::cout << "in foo" << std::endl;
> >}
>
> You forgot to return a Foo.

This time, you're right.

[...]


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Jim Barry" <jim.barry@bigfoot.com>
Date: 1998/06/08
Raw View
Marco Dalla Gasperina wrote in message
<6l6boi$pc9@hpbab.wv.mentorg.com>...
>struct Foo {
>    void operator() { std::cout << "in operator()" << std::endl; }
>};

Presumably you meant "operator()()".

>int main()
>{
>    Foo    foo();
>    foo();
>}

"Foo foo()" is declaration of the function that follows. You forgot to
return a value from "main".

>// then somewhere exists this definition
>Foo foo()
>{
>    std::cout << "in foo" << std::endl;
>}

You forgot to return a Foo.

>Does it compile? Does it link? What is the output?
>This is my own personal GOTW question.

With the above corrections, it outputs the text "in foo".

- Jim

--
Jim Barry, Thermoteknix Systems Ltd., Cambridge, UK.
http://www.thermoteknix.co.uk Queen's Award for Export 1998
Antispam address courtesy of http://www.bigfoot.com
Or e-mail direct: jim at thermoteknix dot co dot 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Marcelo Cantos <marcelo@janus.mds.rmit.edu.au>
Date: 1998/06/02
Raw View
I have a query regarding a small snippet of code:

  class Foo
  {
  public:
      Foo(int);
  };

  class Bar
  {
  public:
      Bar(const Foo&);
  };

  void f(const Bar&) { }

  void g()
  {
      int v = 1;
      Bar bar(Foo(v));
      f(bar);
  }

Most compilers reject the last function call because bar is
interpreted as a function prototype.  However, if we supply a literal
instead of v:

   Bar bar(Foo(1));

It takes it as a construction and hence the f(bar) is correct.

After some discussion, we are still of the opinion that because Foo(v)
can only be interpreted as an object and not as a type, the original
code should have compiled correctly.

Are we wrong in this conclusion?  After all, SunPro, egcs and VC++
can't all be wrong, can they?


Cheers,
Marcelo

--
______________________________________________________________________
Marcelo Cantos, Research Assistant       __/_  marcelo@mds.rmit.edu.au
Multimedia Database Systems Group, RMIT   /       _ Tel 61-3-9282-2497
L2/723 Swanston St, Carlton VIC 3053, Aus/ralia ><_>Fax 61-3-9282-2490
Acknowledgements: errors - me; wisdom - God; sponsorship - RMIT
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Sukanta Ganguly <sganguly@novell.com>
Date: 1998/06/02
Raw View
if your function "g" was like the following

  void g()
  {
      int v = 1;
    Foo    foo(v);
      Bar bar(foo);
      f(bar);
  }
it should work without any problems. I can't say much about the compiler as
to how they interpret as I haven't written them, buit one thing I would say
here is that if I had to parse

      Bar bar(Foo(v));
where "Foo" is the class name then I would certainly take it as a function
call and would generate an error message ("Function Foo() not found")

Later

Marcelo Cantos wrote:

> I have a query regarding a small snippet of code:
>
>   class Foo
>   {
>   public:
>       Foo(int);
>   };
>
>   class Bar
>   {
>   public:
>       Bar(const Foo&);
>   };
>
>   void f(const Bar&) { }
>
>   void g()
>   {
>       int v = 1;
>       Bar bar(Foo(v));
>       f(bar);
>   }
>
> Most compilers reject the last function call because bar is
> interpreted as a function prototype.  However, if we supply a literal
> instead of v:
>
>    Bar bar(Foo(1));
>
> It takes it as a construction and hence the f(bar) is correct.
>
> After some discussion, we are still of the opinion that because Foo(v)
> can only be interpreted as an object and not as a type, the original
> code should have compiled correctly.
>
> Are we wrong in this conclusion?  After all, SunPro, egcs and VC++
> can't all be wrong, can they?
>
> Cheers,
> Marcelo
>
> --
> ______________________________________________________________________
> Marcelo Cantos, Research Assistant       __/_  marcelo@mds.rmit.edu.au
> Multimedia Database Systems Group, RMIT   /       _ Tel 61-3-9282-2497
> L2/723 Swanston St, Carlton VIC 3053, Aus/ralia ><_>Fax 61-3-9282-2490
> Acknowledgements: errors - me; wisdom - God; sponsorship - RMIT
> ---
> [ 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    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]



--

Disclaimer :: The above mentioned views are my own and does not represent my
company's views in any shape, size or form.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Marcelo Cantos <marcelo@janus.mds.rmit.edu.au>
Date: 1998/06/03
Raw View
Sukanta Ganguly <sganguly@novell.com> writes:

> if your function "g" was like the following
>
>   void g()
>   {
>       int v = 1;
>     Foo    foo(v);
>       Bar bar(foo);
>       f(bar);
>   }
> it should work without any problems. I can't say much about the compiler as
> to how they interpret as I haven't written them, buit one thing I would say
> here is that if I had to parse
>
>       Bar bar(Foo(v));
> where "Foo" is the class name then I would certainly take it as a function
> call and would generate an error message ("Function Foo() not found")

I understand that my gut feeling is probably wrong (given that so far
nobody and no compiler has agreed with me).  However, I am trying to
understand why.  Observe the following code:

  class Foo { ... };

  void g()
  {
    int v = 1;
    Foo(v);
  }

My understanding is that Foo(v) should be interpreted as a temporary
instance of class Foo (i.e. as an object).  Why then, when exactly the
same syntactic construct appears inside a parameter list:

  Bar bar(Foo(v));

is it interpreted as something semantically different (i.e. as a
type)?


Cheers,
Marcelo

PS: Is this appropriate to comp.std.c++, or should I be posting across
    to c.l.c++.m?

--
______________________________________________________________________
Marcelo Cantos, Research Assistant       __/_  marcelo@mds.rmit.edu.au
Multimedia Database Systems Group, RMIT   /       _ Tel 61-3-9282-2497
L2/723 Swanston St, Carlton VIC 3053, Aus/ralia ><_>Fax 61-3-9282-2490
Acknowledgements: errors - me; wisdom - God; sponsorship - RMIT


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/06/03
Raw View
In article <bgvhqk2r1v.fsf@janus.mds.rmit.edu.au>,
  Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> wrote:
>   class Foo {
>       public: Foo(int);
>   };
>   class Bar {
>       public: Bar(const Foo&);
>   };
>   void f(const Bar&) { }
>   void g()
>   {
>       int v = 1;
>       Bar bar(Foo(v));
>       f(bar);
>   }
[snip]
> bar is interpreted as a function prototype.  However, if we supply a
> literal instead of v:
>    Bar bar(Foo(1));
> It takes it as a construction and hence the f(bar) is correct.
>
> After some discussion, we are still of the opinion that because Foo(v)
> can only be interpreted as an object and not as a type, the original
> code should have compiled correctly.

The original version is interpreted as
    Bar bar(Foo v);
except you added parenthesis around the argument name v.

Since Bar's constructor has only one argument, you can use
    Bar bar = Foo(v);

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jason Merrill <jason@cygnus.com>
Date: 1998/06/03
Raw View
>>>>> Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> writes:

>       Bar bar(Foo(v));

This is interpreted as

        Bar bar (Foo v);

the parens are optional in a declarator, and the spec says that anything
which can be considered a declarator, is.

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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/06/03
Raw View
Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> writes:

>I understand that my gut feeling is probably wrong (given that so far
>nobody and no compiler has agreed with me).  However, I am trying to
>understand why.  Observe the following code:

>  class Foo { ... };

>  void g()
>  {
>    int v = 1;
>    Foo(v);
>  }

>My understanding is that Foo(v) should be interpreted as a temporary
>instance of class Foo (i.e. as an object).  Why then, when exactly the
>same syntactic construct appears inside a parameter list:

>  Bar bar(Foo(v));

>is it interpreted as something semantically different (i.e. as a
>type)?

Because it isn't the same syntactic construct, it is merely
a similar sequence of tokens. For another example,
 X * Y;
is a declaration of Y as type X* if X is a type, and an
expression statement (multiply X by Y) if X and Y are objects.

The statement
 Foo(v);
is an expression statement because Foo is a type and v
is an object in the current scope. It cannot be interpreted
as a declaration of anything in the context in which it
appears.

But the statement
 Bar bar(Foo(v));
can be interpreted as a declaration statement, declaring
bar to be a function with a parameter of type Foo, with
an unneeded parameter name v and redundant parentheses
around v. Since the parameter list of a function creates
its own scope, the v does not need to refer to local variable
v in function g.

If a statement can be interpreted as a valid declaration, then
it is a declaration. It's a somewhat arbitrary rule to
disambiguate cases that would otherwise be ambiguous.
It ain't pretty, but it's C++.

--
Steve Clamage, stephen.clamage@sun.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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/06/03
Raw View
Marcelo Cantos wrote:

>   void g()
>   {
>       int v = 1;
>       Bar bar(Foo(v));
>       f(bar);
>   }
>
> Most compilers reject the last function call because bar is
> interpreted as a function prototype.

Correct

To get the desired effect:

if you want to/can use the copy ctor of Bar:

    Bar bar = Foo(v);

otherwise, if you prefer direct innitialisation

    Bar bar ((Foo(v)));

> After all, SunPro, egcs and VC++
> can't all be wrong, can they?

Of course they can. Just not in this particular case.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/06/03
Raw View
In article <bgvhqk2r1v.fsf@janus.mds.rmit.edu.au>,
  Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> wrote:
>   void g()
>   {
>       int v = 1;
>       Bar bar(Foo(v));
>       f(bar);
>   }
>
> Most compilers reject the last function call because bar is
> interpreted as a function prototype.  However, if we supply a literal
> instead of v:
>
>    Bar bar(Foo(1));
>
> It takes it as a construction and hence the f(bar) is correct.
>
> After some discussion, we are still of the opinion that because Foo(v)
> can only be interpreted as an object and not as a type, the original
> code should have compiled correctly.

No, Foo(v) can be interpreted as a declaration of a variable v of type
Foo.  Interpreted this way, the statement can be interpreted as a
declaration of a function.

> Are we wrong in this conclusion?  After all, SunPro, egcs and VC++
> can't all be wrong, can they?

They can be, but they aren't in this case.  (I've not verified recently,
but in the past, EVERY compiler I could get my hands on was wrong
in the order of destruction of static variables.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Mark Williams <markw@silicon-spice.com>
Date: 1998/06/03
Raw View
Steve Clamage wrote:

> Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> writes:
>
> >  class Foo { ... };
>
> >  void g()
> >  {
> >    int v = 1;
> >    Foo(v);
> >  }
>
> >My understanding is that Foo(v) should be interpreted as a temporary
> >instance of class Foo (i.e. as an object).  Why then, when exactly the
> >same syntactic construct appears inside a parameter list:
>
> >  Bar bar(Foo(v));
>
> >is it interpreted as something semantically different (i.e. as a
> >type)?
>
> The statement
>         Foo(v);
> is an expression statement because Foo is a type and v
> is an object in the current scope. It cannot be interpreted
> as a declaration of anything in the context in which it
> appears.

Sure it can. It can (and should) be interpreted as a declaration of a
variable named v of type Foo. The fact that there is already a v in the
current scope does not affect matters (except to the extent that the
resultant program contains an illegal redeclaration of v :-)

If current scope were taken into account as you suggest, consider the meaning
of the following program:

void foo()
{
    int (x);  // declare a variable x of type int
    int (x);  // cast x to type int??? I dont think so...
}


Mark Williams
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/06/03
Raw View
In article <6l292n$g3g$1@nnrp1.dejanews.com>,
  AllanW@my-dejanews.com wrote:
>
> In article <bgvhqk2r1v.fsf@janus.mds.rmit.edu.au>,
>   Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> wrote:
> >   class Foo {
> >       public: Foo(int);
> >   };
> >   class Bar {
> >       public: Bar(const Foo&);
> >   };
> >   void f(const Bar&) { }
> >   void g()
> >   {
> >       int v = 1;
> >       Bar bar(Foo(v));
> >       f(bar);
> >   }
> [snip]
> > bar is interpreted as a function prototype.  However, if we supply a
> > literal instead of v:
> >    Bar bar(Foo(1));
> > It takes it as a construction and hence the f(bar) is correct.
> >
> > After some discussion, we are still of the opinion that because Foo(v)
> > can only be interpreted as an object and not as a type, the original
> > code should have compiled correctly.
>
> The original version is interpreted as
>     Bar bar(Foo v);
> except you added parenthesis around the argument name v.
>
> Since Bar's constructor has only one argument, you can use
>     Bar bar = Foo(v);

Or:

    Bar bar( (Foo)( v ) ) ;

(I never use an explicit constructor call with one parameter without
putting the typename in parentheses, just to avoid the ambiguity.)

Or:

    Bar bar( static_cast< Foo >( v ) ) ;

This is actually the same as the above, but uses the new style cast syntax.
(Christian Millour first pointed this out to me.  Although I normally
recommend the new style casts when available, this is really ugly:-).)

Note that the original proposal here requires Bar to have an accessible
copy constructor, whereas my two suggestions don't.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: jkanze@otelo.ibmmail.com
Date: 1998/06/03
Raw View
In article <bg7m2ztm1h.fsf@janus.mds.rmit.edu.au>,
  Marcelo Cantos <marcelo@janus.mds.rmit.edu.au> wrote:
> I understand that my gut feeling is probably wrong (given that so far
> nobody and no compiler has agreed with me).  However, I am trying to
> understand why.  Observe the following code:
>
>   class Foo { ... };
>
>   void g()
>   {
>     int v = 1;
>     Foo(v);
>   }
>
> My understanding is that Foo(v) should be interpreted as a temporary
> instance of class Foo (i.e. as an object).

I'm not sure here.  The rule is that anything that can be interpreted
as a declaration must be interpreted as a declaration, but there are
subtle nuances as to when it gets applied.  A priori, however, the
statement "Foo (v) ;" is a definition of a variable with the name
v and the type Foo.  In this case, of course, such a declaration is
illegal, because there is already a variable with the name v declared
in the same scope.  So in one sense, "Foo (v)" cannot be interpreted
as a declaration, and so shouldn't be.  Except that I don't think that
this sense counts -- I THINK (without having verified it) that the rule
in question only concerns the syntax.  Since the statement has the
correct syntax for a variable declaration, it is a variable declaration,
even though it is not a legal one.  (Actually, I hope this is the case.
I'd hate to think that adding a pair of braces around the statement
changed it from an expression statement to a declaration.)

> Why then, when exactly the
> same syntactic construct appears inside a parameter list:
>
>   Bar bar(Foo(v));
>
> is it interpreted as something semantically different (i.e. as a
> type)?

It's not interpreted as a type, but as a declaration.  Note that in
this case, there is no variable v in the same scope (although there
is one in an enclosing scope), so the declaration is perfectly legal.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Marco Dalla Gasperina" <marcodg@icx.com>
Date: 1998/06/05
Raw View
Marcelo Cantos wrote in message ...
>  void g()
>  {
>      int v = 1;
>      Bar bar(Foo(v));
>      f(bar);
>  }
>
>After some discussion, we are still of the opinion that because Foo(v)
>can only be interpreted as an object and not as a type, the original
>code should have compiled correctly.

The rule is that if it can be interpreted as a declaration, it
will be.  So,

Bar bar(Foo(v)) => Bar bar(Foo v)

(the parens are extraneous).  It is treated as a declaration.

The interesting bit is this:

struct Foo {
    void operator() { std::cout << "in operator()" << std::endl; }
};

int main()
{
    Foo    foo();
    foo();
}

// then somewhere exists this definition
Foo foo()
{
    std::cout << "in foo" << std::endl;
}

Does it compile? Does it link? What is the output?
This is my own personal GOTW question.

marco
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]