Topic: proposal: declarations at expression


Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 13 Feb 2003 23:42:19 +0000 (UTC)
Raw View
choinka@web.de (Gerard Choinka) wrote
> I wish me for c++0x that this kind of syntax will work:
> string s( "Hallo, World!" );
> if((string::size type pos = s.find( "a" )) != string::npos)
>      // work with pos

> Allan W <allan w@my-dejanews.com> wrote:
> > In the current standard, the syntax of the if statement is (6.4/1):
> >     if (condition) statement
> >     if (condition) statement else statement
> > Where condition is:
> >     expression
> >     type-specifier-seq declarator = assignment-expression
> > Class ifstream can usefully convert to bool; it returns true if the
> > file was successfully opened, and false if some error occured.

barfurth@gmx.net (Joerg Barfurth) wrote
> But it can't be copy-initialized, so it can't be declared in a
> condition.

Do you mean like this (also from choinka@web.de (Gerard Choinka))?
> I am use often a similar syntax with streams
> if(ifstream fin( "some.txt" ))
>      // work with fin
> else
>      // error

Clearly it CAN be used in a condition. Not sure what this has to
do with copy-initialization.

> > string::size type can also convert to bool; it is true if the value
> > is zero, and false otherwise. What you can't easily do is compare
> > it to string::npos.
>
> I suppose you mean '... in its own declaration' ?

No, I mean like the first if() statement I quoted above. Did you read it?

> > Is this an omission? You can do what you want this way instead:
> >
> >     string s( "Hallo, World!" );
> >     for(string::size type pos  = s.find( "a" );
> >                           pos != string::npos;
> >                           pos  = string::npos)
> >          // work with pos
> >
> > This is nonintuitive. It also doesn't have anything corresponding to
> > an "else" statement.
>
> If you want an if, use an if. You can either add an extra scope for your
> variable:

The whole point of this thread (all 4 messages of it) was to declare
a variable in the if() statement's scope, but use it in a comparison
other than converting it to bool. As I quoted, and you re-quoted.
Did you read the original poster's comments?

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: barfurth@gmx.net (Joerg Barfurth)
Date: Sat, 15 Feb 2003 00:58:32 +0000 (UTC)
Raw View
Hi Allan,

Allan W <allan_w@my-dejanews.com> wrote:

> choinka@web.de (Gerard Choinka) wrote
> > I wish me for c++0x that this kind of syntax will work:
> > string s( "Hallo, World!" );
> > if((string::size type pos =3D s.find( "a" )) !=3D string::npos)
> >      // work with pos

OK, this is "the first if() statement" you reference  below. Which  of
course is not legal C++.

> > Allan W <allan w@my-dejanews.com> wrote:
> > > In the current standard, the syntax of the if statement is (6.4/1):
> > >     if (condition) statement
> > >     if (condition) statement else statement
> > > Where condition is:
> > >     expression
> > >     type-specifier-seq declarator =3D assignment-expression
> > > Class ifstream can usefully convert to bool; it returns true if the
> > > file was successfully opened, and false if some error occured.

OK, so a  condition can be either an expression or a declaration. If it
is a declaration, then it has to assume the restricted form

   type-specifier-seq declarator =3D assignment-expression

I did call this 'copy-initialization syntax' to distinguish it from the
'direct-initialization syntax' form, which uses an initializer in
parentheses:=20
=20
   type-specifier-seq declarator( expression-list )

A side effect of only allowing the first form is, that the
initialization is copy-initialization.

IOW: Only objects that can be copy-initialized can be declared in  a
condition.
 =20
> barfurth@gmx.net (Joerg Barfurth) wrote
> > But it can't be copy-initialized, so it can't be declared in a
> > condition.

Which I explained more fully now.

> Do you mean like this (also from choinka@web.de (Gerard Choinka))?
> > I am use often a similar syntax with streams
> > if(ifstream fin( "some.txt" ))
> >      // work with fin
> > else
> >      // error

Right. That is what I meant. This syntax is illegal. If some compilers
accept this, that  is an extension:  If they don't issue a diagnostic
they are not compliant to the standard in this respect.

> Clearly it CAN be used in a condition. Not sure what this has to
> do with copy-initialization.

As I explained above, this clearly CAN'T be used in a condition.
=20
> > > string::size type can also convert to bool; it is true if the value
> > > is zero, and false otherwise. What you can't easily do is compare
> > > it to string::npos.
> >=20
> > I suppose you mean '... in its own declaration' ?=20
>=20
> No, I mean like the first if() statement I quoted above. Did you read i=
t?

Yes I had read it. Here I simply was picking a nit: Of course it is not
more difficult to compare a size_type declared in a condition to
string:npos in general.. But you can't easily do that comparison in the
condition that is its declaration. Maybe this was missing a smiley or
"scnr".

> > > Is this an omission? You can do what you want this way instead:
> > >=20
> > >     string s( "Hallo, World!" );
> > >     for(string::size type pos  =3D s.find( "a" );
> > >                           pos !=3D string::npos;
> > >                           pos  =3D string::npos)
> > >          // work with pos
> > >=20
> > > This is nonintuitive. It also doesn't have anything corresponding t=
o
> > > an "else" statement.
> >=20
> > If you want an if, use an if. You can either add an extra scope for y=
our
> > variable:
>=20
> The whole point of this thread (all 4 messages of it) was to declare
> a variable in the if() statement's scope, but use it in a comparison
> other than converting it to bool. As I quoted, and you re-quoted.
> Did you read the original poster's comments?

Yes I did. And we all know that this is not legal. And IMHO that is a
Good Thing.  Both the expression syntax and the declaration syntax in
C++ are complicated enough as is. I don't thing adding yet another twist
by allowing a declaration as subexpression would be helpful.

And I showed several workarounds to achieve the objective of the
original post without requiring a language change.

Regards, Joerg

--=20
J=F6rg Barfurth                         barfurth@gmx.net
<<<<<<<<<<<<< using std::disclaimer;  <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Software Developer                    http://util.openoffice.org
StarOffice Configuration    # Deutsch:http://de.openoffice.org

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 7 Feb 2003 20:04:44 +0000 (UTC)
Raw View
choinka@web.de (Gerard Choinka) wrote
> I wish me for c++0x that this kind of syntax will work:

> string s( "Hallo, World!" );
> if((string::size_type pos = s.find( "a" )) != string::npos)
>      // work with pos

In the current standard, the syntax of the if statement is (6.4/1):
    if (condition) statement
    if (condition) statement else statement
Where condition is:
    expression
    type-specifier-seq declarator = assignment-expression

And in (6.4/4):
    The value of a condition that is an initialized declaration in a
    statement other than a switch statement is the value of the
    declared variable implicitly converted to type bool. If that
    conversion is ill-formed, the program is ill-formed.

Class ifstream can usefully convert to bool; it returns true if the
file was successfully opened, and false if some error occured.

string::size_type can also convert to bool; it is true if the value
is zero, and false otherwise. What you can't easily do is compare
it to string::npos.

Is this an omission? You can do what you want this way instead:

    string s( "Hallo, World!" );
    for(string::size_type pos  = s.find( "a" );
                          pos != string::npos;
                          pos  = string::npos)
         // work with pos

This is nonintuitive. It also doesn't have anything corresponding to
an "else" statement.

In general, I think it would be able to declare a variable inside of
any expression.

    int i = (int j = somefunc()) * 2;

equivalent to
    int j = somefunc();
    int i = j * 2;

Another benefit of this syntax is that it would allow a for() loop to
declare two different types of controlled variables.

    for (int i = (std::string s("Hello")).length()-1; i>=0; --i)

This for() loop declares variables s (a std::string) and i (an int),
which is impossible today. I can't think of any better syntax than this.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: barfurth@gmx.net (Joerg Barfurth)
Date: Sat, 8 Feb 2003 00:19:51 +0000 (UTC)
Raw View
Allan W <allan_w@my-dejanews.com> wrote:

> > string s( "Hallo, World!" );
> > if((string::size_type pos =3D s.find( "a" )) !=3D string::npos)
> >      // work with pos
>=20
> In the current standard, the syntax of the if statement is (6.4/1):
>     if (condition) statement
>     if (condition) statement else statement
> Where condition is:
>     expression
>     type-specifier-seq declarator =3D assignment-expression

> Class ifstream can usefully convert to bool; it returns true if the
> file was successfully opened, and false if some error occured.

But it can't be copy-initialized, so it can't be declared in a
condition.
=20
> string::size_type can also convert to bool; it is true if the value
> is zero, and false otherwise. What you can't easily do is compare
> it to string::npos.

I suppose you mean '... in its own declaration' ?=20

> Is this an omission? You can do what you want this way instead:
>=20
>     string s( "Hallo, World!" );
>     for(string::size_type pos  =3D s.find( "a" );
>                           pos !=3D string::npos;
>                           pos  =3D string::npos)
>          // work with pos
>=20
> This is nonintuitive. It also doesn't have anything corresponding to
> an "else" statement.

If you want an if, use an if. You can either add an extra scope for your
variable:

  string s( "Hallo, World!" );
  {
    string::size_type pos =3D s.find( "a" );
    if(pos !=3D string::npos)
       // work with pos

  }

or declare a variable that converted to bool yields the correct result:

  if (string::size_type rpos =3D string::npos - s.find( "a" ))
  {
       string::size_type pos =3D string::npos - rpos;
       // work with pos
  }

or use a helper class that evaluates the right condition:

  struct stringpos
  {
    string:size_type pos
    stringpos(string:size_type pos) : pos(pos) {}

    operator bool() const { return pos !=3D string::npos; }=20
  };

  if (stringpos pos =3D s.find( "a" ))
       // work with pos.pos

Comparing to zero has a tradition of being special in C and C++.

Ciao, J=F6rg

--=20
J=F6rg Barfurth                         barfurth@gmx.net
<<<<<<<<<<<<< using std::disclaimer;  <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Software Developer                    http://util.openoffice.org
StarOffice Configuration    # Deutsch:http://de.openoffice.org

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: choinka@web.de (Gerard Choinka)
Date: Thu, 6 Feb 2003 00:52:25 +0000 (UTC)
Raw View
Hallo
I wish me for c++0x that this kind of syntax will work:
string s( "Hallo, World!" );
if((string::size_type pos =3D s.find( "a" )) !=3D string::npos)
     // work with pos

I am use often a similar syntax with streams
if(ifstream fin( "some.txt" ))
     // work with fin
else
     // error

and it works very well, the fin object is more local and don=92t waste my=
=20
resources.
How is the feasibility?


-------
Gerard Choinka alias Dimah @ www.c-plusplus.de

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]