Topic: = and == operators still visually ambiguous


Author: John Kewley <kewley@cscs.ch>
Date: 2000/06/29
Raw View
A technique that I use (and was initially very sceptical of)
is to use (lack of) whitespace when writing code to
represent the commutative balance of == and not for =

eg

a= 5;
if (a == 5) {...}

note that

if (a = 5)
to me looks strange since I would expect

if (a= 5)
for an assignment

Try it, after a short while the dodgy assigments stand out like
sore thumbs.

Of course if you use decent syntax checkers or compilers, these
strange uses of assigment are highlighted for you.

--
John M. Kewley                             Tel: +41 (0) 91 610 8248
Head of Software Engineering               Fax: +41 (0) 91 610 8282
Swiss Center for Scientific Computing      mailto:John.Kewley@cscs.ch
Via Cantonale, CH-6928 Manno, Switzerland  http://www.cscs.ch/%7Ekewley/

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/07/08
Raw View
John Kewley wrote:
> A technique that I use (and was initially very sceptical of)
> is to use (lack of) whitespace when writing code to
> represent the commutative balance of == and not for =
[...]
>
> Of course if you use decent syntax checkers or compilers, these
> strange uses of assigment are highlighted for you.

A decent language definition would disallow assignment expressions
as conditional expressions, or better yet, disallow non-boolean
expressions as conditional expressions altogether.

When I need an assignment followed by a conditional test of the
just-assigned value, I can always rewrite it as two separate
expressions:

    // A
    if ((ch = getchar()) != EOF) ...       // bad

    ch = getchar();                        // better
    if (ch != EOF) ...

    // B
    while ((ch = getchar()) != EOF) ...    // bad

    while (ch = getchar(), ch != EOF) ...  // better

Of course, this doesn't solve the =/== problem, but it does
prove that C/C++ doesn't need to allow assignment expressions as
conditional expressions.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: kanze@gabi-soft.de
Date: 2000/06/19
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  Jonathan de Boyne Pollard wrote:

|>  > DT> (I really wish C++ had made it illegal for conditional
|>  > expressions DT> to be composed of anything other than boolean
|>  > expressions. [...])

|>  > JdeBP> It did.  A program is ill-formed if the the expression in
|>  > an JdeBP> `if' (or `for' or `while') statement cannot be
|>  > implicitly JdeBP> converted to `bool'.  See 6.4(4).

|>  > JK> That's not the same as requiring a boolean expression. It
|>  > allows JK> non-boolean expressions that can be implicitily
|>  > converted to JK> 'bool'.

|>  > It imposes the very constraint that David says that he wishes for,
|>  > however.

|>  The constraint that (I think) David asks for is very different from
|>  what you're saying, and solves a wider range of problems. To take it
|>  to it's logical extreme, the following changes would need to be be
|>  made to the C++ language:

|>  1. Remove all implicit conversions to and from 'bool'.
|>  2. Remove cast conversions to and from 'bool'. Conversions to 'bool'
|>  could only be achieved by explicitly using "!=3D0"; conversions from
|>  'bool' could only be done by explicitly using "?1:0".

Did he really insist that explicit conversions be removed?

|>  3. Require that the condition which appears in if(), for(), while(), =
do
|>  while() statements, and the logical-or-expression that is the left
|>  operand in coditional-expressions, must have boolean type.
|>  4. optional: the constant-expression in a #if preprocessing statement
|>  must also have boolean type.

|>  > It is not the case that the constraint that he desires does not
|>  > exist in the C++ language, because it does. ...

|>  The constraints that would be imposed by these changes defininately
|>  do NOT exist in the C++ language as it currently stands. Such
|>  changes would be incompatible with most existing C++ code, so I
|>  don't expect that they could ever actually happen. However, I think
|>  that they would make the language slightly less error prone, and
|>  would encourage slightly clearer code.

Note that the original proposal for bool included the deprecation of the
implicit conversions.  This part of the proposal was removed in order to
make the proposal acceptable.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/06/20
Raw View
kanze@gabi-soft.de wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> |>  Jonathan de Boyne Pollard wrote:
>
> |>  > DT> (I really wish C++ had made it illegal for conditional
> |>  > expressions DT> to be composed of anything other than boolean
> |>  > expressions. [...])
>
> |>  > JdeBP> It did.  A program is ill-formed if the the expression in
> |>  > an JdeBP> `if' (or `for' or `while') statement cannot be
> |>  > implicitly JdeBP> converted to `bool'.  See 6.4(4).
>
> |>  > JK> That's not the same as requiring a boolean expression. It
> |>  > allows JK> non-boolean expressions that can be implicitily
> |>  > converted to JK> 'bool'.
>
> |>  > It imposes the very constraint that David says that he wishes for,
> |>  > however.
>
> |>  The constraint that (I think) David asks for is very different from
> |>  what you're saying, and solves a wider range of problems. To take it
> |>  to it's logical extreme, the following changes would need to be be
> |>  made to the C++ language:
>
> |>  1. Remove all implicit conversions to and from 'bool'.
> |>  2. Remove cast conversions to and from 'bool'. Conversions to 'bool'
> |>  could only be achieved by explicitly using "!=0"; conversions from
> |>  'bool' could only be done by explicitly using "?1:0".
>
> Did he really insist that explicit conversions be removed?

He did not provide as much detail as I did. I'm taking his suggestion
"to it's logical extreme", which may be stronger than he intended. The
language provides alternatives constructs that could have been used to
achieve the same effects as a conversion: "!=0" and "?1:0". Those
constructs are arguably clearer than the corresponding conversions,
whether implicit or explicit.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/31
Raw View
Jonathan de Boyne Pollard wrote:
>
> DT> (I really wish C++ had made it illegal for conditional expressions
> DT> to be composed of anything other than boolean expressions. [...])
>
> JdeBP> It did.  A program is ill-formed if the the expression in an
> JdeBP> `if' (or `for' or `while') statement cannot be implicitly
> JdeBP> converted to `bool'.  See 6.4(4).
>
> JK> That's not the same as requiring a boolean expression. It allows
> JK> non-boolean expressions that can be implicitily converted to
> JK> 'bool'.
>
> It imposes the very constraint that David says that he wishes for, however.

The constraint that (I think) David asks for is very different from what
you're saying, and solves a wider range of problems. To take it to it's
logical extreme, the following changes would need to be be made to the
C++ language:

1. Remove all implicit conversions to and from 'bool'.
2. Remove cast conversions to and from 'bool'. Conversions to 'bool'
could only be achieved by explicitly using "!=0"; conversions from
'bool' could only be done by explicitly using "?1:0".
3. Require that the condition which appears in if(), for(), while(), do
while() statements, and the logical-or-expression that is the left
operand in coditional-expressions, must have boolean type.
4. optional: the constant-expression in a #if preprocessing statement
must also have boolean type.

> It is not the case that the constraint that he desires does not exist in the
> C++ language, because it does. ...

The constraints that would be imposed by these changes defininately do
NOT exist in the C++ language as it currently stands. Such changes would
be incompatible with most existing C++ code, so I don't expect that they
could ever actually happen. However, I think that they would make the
language slightly less error prone, and would encourage slightly clearer
code.

---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/28
Raw View
In article <392E3113.11926265@tesco.net>, Jonathan de Boyne Pollard
<J.deBoynePollard@tesco.net> writes
>FG> My rule is:
>FG>
>FG>     Define a variable no sooner than you can initialise it
>FG>     and no later than its point of first use.
>
>The second part of your rule doesn't buy you very much.  How could one
>possibly flout it even if one wanted to ?  (-:

Of course it doesn't but it focuses the mind of the student and reminds
them that just because you are ready to initialise does not mean you
should automatically declare.


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/29
Raw View
Jonathan de Boyne Pollard wrote:
>
> FG> My rule is:
> FG>
> FG>     Define a variable no sooner than you can initialise it
> FG>     and no later than its point of first use.
>
> The second part of your rule doesn't buy you very much.  How could one
> possibly flout it even if one wanted to ?  (-:

There are languages where the first use of an identifier implicitly
defines it; C++ isn't one of them. Therefore, it's quite possible to
write code where the declaration follows the first use. In that case,
the first use will occur outside the scope of the declaration, and the
declaration will not be found by name lookup. According to 3.4.1 p1: "If
no declaration is found, the program is ill-formed." Most C++
implementations won't translate such code*. The purpose of the second
part of that rule is to avoid wasting time attempting to translate such
code.

* - a C++ implementation is never required to reject a program just
because it's ill-formed. Implicit declaration with type deduction based
upon the type of the initializing expression is a possible extension,
though a diagnostic would be required in that case (1.4 p8).

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/05/26
Raw View
DT> (I really wish C++ had made it illegal for conditional expressions
DT> to be composed of anything other than boolean expressions. [...])

JdeBP> It did.  A program is ill-formed if the the expression in an
JdeBP> `if' (or `for' or `while') statement cannot be implicitly
JdeBP> converted to `bool'.  See 6.4(4).

JK> That's not the same as requiring a boolean expression. It allows
JK> non-boolean expressions that can be implicitily converted to
JK> 'bool'.

It imposes the very constraint that David says that he wishes for, however.
It is not the case that the constraint that he desires does not exist in the
C++ language, because it does.  David's problem is that he isn't actually
wishing for the right thing.

He is not alone, incidentally.  This thread has concentrated upon criticising
assignment expressions, and a few participants have expressed their wishes
that assignments should not be expresssions, but a separate class of
statements in their own right (as they are in, say, BASIC).  Again, this is
wishing for the wrong thing.  As the subject line tells us, the problem is
*not* that one can perform assignments within expressions.  The problem is
that the '=' operator has a spelling that is very close to the spelling of the
'==' operator.  The two are "visually ambiguous".  A much *better* wish, for
those people who rate this as a major problem to be making, would be that
either the '=' or the '==' operator be re-spelled.  If this wish were granted,
they could keep the ability to have assignments within expressions (which is a
language feature that I for one, and I suspect many others, find very handy
and would object to being removed) whilst removing the visual ambiguity that
is the actual cause for complaint that they have here.

In other words, a more appropriate wish (rather than prohibiting assignments
within expressions) would be for the addition of either '::=' or 'eq_eq' to
the list of alternative tokens in 2.5 .  (The latter is more preferable, since
it is more consistent with the other alternative tokens such as 'and_eq' and
'not_eq'.  But I suspect that, alas, '::=' combined with an implementation
option to warn about all instances of '=' would solve the actual problem at
hand better.)

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/05/27
Raw View
FG> My rule is:
FG>
FG>     Define a variable no sooner than you can initialise it
FG>     and no later than its point of first use.

The second part of your rule doesn't buy you very much.  How could one
possibly flout it even if one wanted to ?  (-:

---
[ 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: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/05/10
Raw View

>>>>>>>>>>>>>>>>>> Urspr=FCngliche Nachricht <<<<<<<<<<<<<<<<<<

Am 10.05.00, 04:55:17, schrieb Michiel Salters <salters@lucent.com> zum=20
Thema Re: =3D and =3D=3D operators still visually ambiguous:


> Sebastian Moleski wrote:

> > Saying things like

> > if (X *x =3D dynamic_cast<X *>(y))

> > say that an x should be defined if an y can be dynamically casted to
> > an X*.=20

> Actually x is always defined, even if the condition is false. If
> it weren't, the following code would be illegal instead of silly:

> if (X *x =3D dynamic_cast<X *>(y))
> {
>       ;
> } else
> {
>       x;
> }

This is true. But if you don't add an 'else' branch, x wont be defined in=
=20
any scope where both:
- '*y' is not an X, and=20
- x can be used

If you do add an else 'branch', you still have confined the declarative=20
region of 'x' to one (possibly compound) statement. And from that=20
statement it is not far to the condition, which clearly indicates that x=20
wont be of much use in that branch.

> Another mystery to me is that you read X *x =3D dynamic_cast<X *>(y) as
> "define some variable if and only if _some_condition_ is true".
> (Emphasis mine). There is no condition in that expression!
> Conditions are <,>,<=3D,>=3D,=3D=3D and !=3D, after all.

Your argument is somewhat misleading, IMHO:

Firstly, Sebastian has 'can be dynamically casted to an X*' for your=20
'_some_condition_ is true'. This is clearly a condition, but in a broader=
=20
sense than that given by C++ Syntax.=20

Then you go on to show the obvious - that this is not a condition in the=20
syntactical sense.
=20
Particularly misleading is the use of '... is true', as this suggests=20
that '_some_condition_' needs to have the form of an expression of type=20
bool. Read this way your rewording of the original statement is simply wr=
ong.

BTW: a condition does not need to contain a comparison operator, even if=20
you shun implicit conversion to bool.

> What happens is that if the conditional of an if-statement is a
> pointer, NULL is mapped to false and any other pointer to true.
> Readability is IMO improved by preferring an explicit test over
> this implicit conversion.

In many cases this may be true. I prefer explicit comparison to an=20
appropriate constant in most cases myself.=20

But in this case:

- There is an idiom readily recognized once you know it.

- There is the advantage of limiting the scope of x to the smallest=20
possible, initializing x in its definition and keeping that near the area=
=20
where x can validly be used.

- As the original wording suggests, dynamic_cast should be seen as=20
evaluating a condition. The condition evaluated is '_argument_ has=20
runtime type _type_'.=20

Cleverly, the designers of dynamic_cast defined the result in such a way=20
that implicit conversion to bool yields true iff the cast succeeds. So=20
using the results of a dynamic_cast in a '_Condition_' evaluates the=20
above-mentioned condition. Once this has been realized, the=20
technicalities of implicit conversions underneath can be forgotten.=20

Seen this way, the if-statement above is a better=20
(information-preserving) alternative to:
    if (is_really_a<X*>(y))
        ....

or (closer, but not too useful)
    if (bool itsAnX =3D is_really_a<X*>(y))
        ...

Where=20
    template <class T, class U>=20
    bool is_really_a(U* y) {=20
        return dynamic_cast<T>(y) !=3D 0;
    }

-- J=F6rg Barfurth


---
[ 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: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/05/10
Raw View

>>>>>>>>>>>>>>>>>> Urspr=FCngliche Nachricht <<<<<<<<<<<<<<<<<<

Am 10.05.00, 04:56:29, schrieb James Kuyper <kuyper@wizard.net> zum Thema=
=20
Re: =3D and =3D=3D operators still visually ambiguous:


> David R Tribble wrote:
> ....
> > But, if you absolutely insist on puttin all three semantic operations
> > (definition, assignment/initialization, test for null) together
> > into a single statement, you can always do this:
> >
> >     if (TCircle *c =3D dynamic_cast<TCircle *>(shapePtr), c !=3D NULL=
)
> >     {
> >         /* some code */
> >     }

> Problem: I believe that the above code can't legally be parsed the way
> you intend.=20

Agreed

>The thing inside the if() must be a

> _condition_:
>       _expression_
>       _type-specifier-seq_ _declarator_ =3D _assignment-expression_

> I believe that you're trying to interpret the _condition_ as an

> _expression_:
>       _expression_ , _assignment-expression_

> But that would require interpreting the definition of 'c' as an
> expression, and it isn't. I believe that the above code must be
> interpreted as the second kind of _condition_.=20

Which it can't.

> In other words, it's
> equivalent to

No, because '_expression_ , _assignment-expression_' is not an=20
'_assignment-expression_'.=20

> if(TCircle *c =3D (dynamic_cast<TCircle *>(shapePtr), c !=3D NULL) )
> {
>       /* some code */
> }

> Which fails horribly for at least six different reasons.

Among them, of course, that a 'bool' isn't convertible to a 'TCircle*'

-- J=F6rg


---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/05/10
Raw View
James Kuyper wrote:
>
> David R Tribble wrote:
> ....
>> Sebastian Moleski wrote:
>> > Everynbody has the right to express his wrong opinion. <g>
>> >
>> > I don't see how not having an implict type conversion would help me
>> > with code like the following:
>> >
>> > if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
>> >     /* some code */
>> > }
>>
>> What would help with such code is to pull the declaration and
>> initialization out of the conditional expression.  Imagine the poor
>> sap who gets to maintain this code, having a difficult time locating
>> the variable definition.
>
> Yes - it's so difficult looking in places closely related to the
> actual use of the variable. It's so much easier to look farther away.

It is if you're used to looking in only one place, at the top of the
function block, rather than in multiple places, starting with the
innermost scope and working your way upwards and outwards.  I am
in the former category of programmers.

The function arguments are declared at the top, even though they may
not be used until much further down in the function.

And there is the risk of hiding names in an outer scope, which can
make for confusing code.

There are various opinions about what makes for the most readable
code.  The following is an extract from the Java coding conventions
document from Sun (which is not always adhered to by Sun employees),
which can be applied to C++ programming style:

  6.3 Placement

  Put declarations only at the beginning of blocks.  (A block is any
  code surrounded by curly braces "{" and "}".)  Don't wait to declare
  variables until their first use; it can confuse the unwary programmer
  and hamper code portability within the scope.

    void myMethod() {
        int int1 = 0;         // beginning of method block

        if (condition) {
            int int2 = 0;     // beginning of "if" block
            ...
        }
    }

  The one exception to the rule is indexes of for loops, which in Java
  can be declared in the for statement:

    for (int i = 0; i < maxLoops; i++) { ... }

  Avoid local declarations that hide declarations at higher levels.
  For example, do not declare the same variable name in an inner block:

    int count;
    ...

    myMethod() {
        if (condition) {
            int count = 0;     // AVOID!
            ...
        }
        ...
    }

[Extracted from http://java.sun.com/docs/codeconv/index.html]

I tend to agree with their reasons.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: David R Tribble <david@tribble.com>
Date: 2000/05/10
Raw View
J=F6rg Barfurth wrote:
>=20
> David R Tribble <david@tribble.com> wrote:
> > Both of which are obviously clearer than:
>=20
> I miss some smileys here and below.

;-)

>>     int  c;
>>     while (cin >> c, c !=3D EOF)            // [A]
>>         ...

> Which is also illegal.

You mean incorrect, not illegal.  My compiler accepts it without
warnings.

> I would prefer:
>=20
>     int c; // though I don't like uninitialized variables :-(
>     while(cin >> c)
>         // ....
>=20
> .. which clearly expresses: While '>>' does extract an integer from
> cin into c, do ...

No, it means: While '>>' extracts a non-zero integer into c, do ...

[...]
> I dislike the comma operator though. I find it a lot harder to read.

Harder to read than an extra set of parentheses?

    while ((cin >> c) !=3D EOF) ...

> Although I miss the smiley, I assume we agree that (a) there is no
> real difference in efficiency between all these examples,
> (b) premature optimization is the root of much evil,
> (c) readability and maintainability are usually much more important
> than local optimizations

;-)

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: kanze@gabi-soft.de
Date: 2000/05/10
Raw View
David R Tribble <david@tribble.com> writes:

|>  AllanW wrote:

|>  > jeffturneresq@my-deja.com wrote:
|>  >> ...  One is actually _encouraged_ to write code such as

|>  >>       while((cin >> int c) !=3D EOF){ ...         // [1]

|>  >> because it improves efficiency to declare a variable where it is
|>  >> initialized.  Removing the ability to initialize variables within
|>  >> conditional statements would actually DETRACT from C++ in addition=
 to
|>  >> the other stated reasons.

|>  > You probably meant
|>  >=20
|>  >         for(int c; (cin>>c) !=3D EOF; ) { // ...    // [2]

|>  Both of which are obviously clearer than:

|>      int  c;
|>      while (cin >> c, c !=3D EOF)            // [A]
|>          ...

|>  Or even:

|>      for (int c; cin >> c, c !=3D EOF; )     // [B]
|>          ...

|>  It's obvious that my code examples [A] and [B] are much, much less
|>  efficient than [1] or [2], and therefore should be considered bad
|>  style.  Efficiency, after all, is the primary concern of good code.

Well, it's obvious int the last two cases that the code is wrong, while
it is easy to overlook the (same) error in the first.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/05/10
Raw View
David R Tribble <david@tribble.com> wrote:
>> But, if you absolutely insist on puttin all three semantic operations
>> (definition, assignment/initialization, test for null) together
>> into a single statement, you can always do this:
>>
>>     if (TCircle *c = dynamic_cast<TCircle *>(shapePtr), c != NULL)

John Potter wrote:
> I don't think so.  Note that the condition may be either a declaration
> or an expression, but not both.

My mistake.  Looks like the code has to remain ugly if you want to do
all three semantic operations (variable definition, variable
assignment, and conditional expression) in one place.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/10
Raw View
J=F6rg Barfurth wrote:
....
> Your argument is somewhat misleading, IMHO:
>=20
> Firstly, Sebastian has 'can be dynamically casted to an X*' for your
> '_some_condition_ is true'. This is clearly a condition, but in a broad=
er
> sense than that given by C++ Syntax.

Actually, it is a condition in precisely the sense give by C++ syntax.

> Then you go on to show the obvious - that this is not a condition in th=
e
> syntactical sense.

Except that it is a condition in the syntactic sense. See section 6.4
p1.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/10
Raw View
David R Tribble wrote:
>
> James Kuyper wrote:
> >
> > David R Tribble wrote:
> > ....
> >> Sebastian Moleski wrote:
> >> > Everynbody has the right to express his wrong opinion. <g>
> >> >
> >> > I don't see how not having an implict type conversion would help me
> >> > with code like the following:
> >> >
> >> > if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
> >> >     /* some code */
> >> > }
> >>
> >> What would help with such code is to pull the declaration and
> >> initialization out of the conditional expression.  Imagine the poor
> >> sap who gets to maintain this code, having a difficult time locating
> >> the variable definition.
> >
> > Yes - it's so difficult looking in places closely related to the
> > actual use of the variable. It's so much easier to look farther away.
>
> It is if you're used to looking in only one place, at the top of the
> function block, rather than in multiple places, starting with the
> innermost scope and working your way upwards and outwards.  I am
> in the former category of programmers.

I'm in the latter; I search backward from the point of use. This is
partly due to the fact that I'm current required to code according to
standards that require a comment typically containing about 40 lines of
documentation. This comment is required to be placed between the '{' at
the start of a function declaration, and the first line of code in that
function. I can't defend this requirement, but I do have to code
according to it. This means that the vi command which goes to the start
of the function isn't very helpful.

However, I search that way mainly because I work on code that many other
people have touched. I know that a variable can be defined almost
anywhere, so there's not much point in pretending that there's a
guarantee that it will be defined only in the 'usual' place. If I look
only in the usual place, I've a chance of missing the real definition.

---
[ 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: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/05/10
Raw View
Am 10.05.00, 11:39:28, schrieb David R Tribble <david@tribble.com> zum=20
Thema Re: =3D and =3D=3D operators still visually ambiguous:


> J=F6rg Barfurth wrote:
> >
> > David R Tribble <david@tribble.com> wrote:

> >>     int  c;
> >>     while (cin >> c, c !=3D EOF)            // [A]
> >>         ...

> > Which is also illegal.

> You mean incorrect, not illegal.  My compiler accepts it without
> warnings.

You are right. I saw what I expected to see: 'cin !=3D EOF'. The original=
=20
version did that.
Your version just rejects a value of c=3D=3D-1. Even if cin was bad() to=20
begin with and therefore c is never initialized.

> > I would prefer:
> >
> >     int c; // though I don't like uninitialized variables :-(
> >     while(cin >> c)
> >         // ....
> >
> > .. which clearly expresses: While '>>' does extract an integer from
> > cin into c, do ...

> No, it means: While '>>' extracts a non-zero integer into c, do ...

No. Under the hood it is ugly: The statement is evaluated as:
 while( implicit_cast<bool>(cin.operator >> (int&). operator void*() ) )=20
...

So operator>> returns cin, that has a conversion to void*, and void* can =
be=20
implicitly converted to bool. The conversion to void* returns NULL iif=20
cin.fail(). This way you can convince yourself that a stream extraction=20
will convert to true iif the extraction succeeds. The value extracted doe=
s=20
not matter.

Once you understood this, you can forget about the dirty detail. Instead=20
the exprssion should be read as I said.

> [...]
> > I dislike the comma operator though. I find it a lot harder to read.

> Harder to read than an extra set of parentheses?

>     while ((cin >> c) !=3D EOF) ...

Back to ill-formed here. An istream cannot be compared to an int (not=20
even using operator void*). The only exception is a NULL pointer=20
constant. So actually the following compile (and do the same as my=20
version).

    while ( (cin >> c) !=3D NULL )
    while ( (cin >> c) !=3D false )
    while ( (cin >> c) !=3D (void*)0)
and the equivalent
    while ( cin >> c, cin !=3D 0 )
    while ( cin >> c, cin !=3D false )
    while ( cin !=3D c, cin !=3D (void*)0 )

If you really need an explicit and meaningful condition, comparisons wont=
=20
do it. Try:

    while ( !(cin >> c).fail() ) ...
or
    while ( cin >> c, !cin.fail() ) ...

The first one is ugly and hard to read.=20

The second one is better. But IMHO it still obscures the fact that we are=
=20
interested in the success of the extraction and not in the state of cin=20
after the operation (although both are closely related). This comes=20
about, because we artificially try to seperate the operation=20
(side-effect) from evaluating whether that operation succeeded.

Also, if we really think the extraction should not be part of the=20
condition, we should get it out of the brace:

  while (1) {
    int c;
    cin >> c;

    if (cin.fail()) break;
    ...
  }

I think there are languages (ADA ?), where this would be the appropriate=20
idiom. It even provides for correct scoping of c. But breaking out of the=
=20
middle of a loop is not too highly regarded in C/C++.

I nevertheless would go for that last version, if there weren't such a=20
readable, compact, well-known idiom:=20

    while(cin>>c)
        ...

-- J=F6rg Barfurth


---
[ 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: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/05/10
Raw View
"David R Tribble" <david@tribble.com> wrote in message
news:39189D8E.4929FA95@tribble.com...
> There are various opinions about what makes for the most readable
> code.  The following is an extract from the Java coding conventions
> document from Sun (which is not always adhered to by Sun employees),
> which can be applied to C++ programming style:
>
> [Extracted from http://java.sun.com/docs/codeconv/index.html]
>
>   6.3 Placement
>
>   Put declarations only at the beginning of blocks.  (A block is any
>   code surrounded by curly braces "{" and "}".)  Don't wait to declare
>   variables until their first use; it can confuse the unwary programmer
>   and hamper code portability within the scope.
>
>     void myMethod() {
>         int int1 = 0;         // beginning of method block
>
>         if (condition) {
>             int int2 = 0;     // beginning of "if" block
>             ...
>         }
>     }

If the block (or function) is long enough for the placement to be an
issue, then I would prefer the freedom to to declare locals "const".
(So, I'm in the "declare at first use" camp.)

    {
        ... // various processing
        int const n = /*expression*/;
        ... // more code that uses "n" without modification
    }

>   The one exception to the rule is indexes of for loops, which in Java
>   can be declared in the for statement:
>
>     for (int i = 0; i < maxLoops; i++) { ... }

But in C++, the scope of i is the following block (as it is for the
"if" statement that introduced this sub-topic), so I would argue that
this (and the "if" that your objected to) actually follow Sun's guide.

>   Avoid local declarations that hide declarations at higher levels.
>   For example, do not declare the same variable name in an inner block:
>
>     int count;
>     ...
>
>     myMethod() {
>         if (condition) {
>             int count = 0;     // AVOID!
>             ...
>         }
>         ...
>     }

Agreed, although I tend to re-use names like "i" for a count
that isn't used for any purpose other than to control a loop.
Then again, if my compiler issued a warning about this, I would
probably change my style rather than disable the warning.

---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/10
Raw View
In article <39189D8E.4929FA95@tribble.com>, David R Tribble
<david@tribble.com> writes
>There are various opinions about what makes for the most readable
>code.  The following is an extract from the Java coding conventions
>document from Sun (which is not always adhered to by Sun employees),
>which can be applied to C++ programming style:
Yes, there are various opinions but a very important factor is when you
can initialise a variable.  Uninitialised variables are a prime cause of
bugs.

My rule is:

Define a variable no sooner than you can initialise it and no later than
its point of first use.

If you get in the habit of writing neat short functions that often
defines exactly where you define a local variable.  If you are having
problems finding variable definitions consider the size of your
functions.

Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: kanze@gabi-soft.de
Date: 2000/05/11
Raw View
J=F6rg Barfurth <joerg.barfurth@attglobal.net> writes:

|>  Am 09.05.00, 07:35:30, schrieb David R Tribble <david@tribble.com> zu=
m=20
|>  Thema Re: =3D and =3D=3D operators still visually ambiguous:

|>  > > jeffturneresq@my-deja.com wrote:
|>  > >> ...  One is actually _encouraged_ to write code such as
|>  > >>
|>  > >>       while((cin >> int c) !=3D EOF){ ...         // [1]

|>  Of course this is ill-formed. Some people miss a way to initialize a=20
|>  variable from a stream.

|>  > > You probably meant
|>  > >
|>  > >         for(int c; (cin>>c) !=3D EOF; ) { // ...    // [2]

|>  Which I dislike as well. I prefer to use 'for' only if all three part=
s=20
|>  apply: Initializing loop control, checking the loop condition and=20
|>  preparing the next round.

|>  > Both of which are obviously clearer than:

|>  I miss some smileys here and below.
|> =20
|>  >     int  c;
|>  >     while (cin >> c, c !=3D EOF)            // [A]
|>  >         ...
|>  Which is also illegal.

It's perfectly legal (well formed).  It just doesn't do anything useful,
and certainly not what was intended:-).  Of course, written this way,
the error is obvious, whereas in the first case, you really have to look
twice.  My suggestion (using a for):

    for ( int c =3D cin.get() ; c !=3D EOF ; c =3D cin.get() )
        ...

If it was really intended to read an int, of course:

    int i ;
    for ( cin >> i ; ! cin.fail() ; cin >> i )
        ...

At least, that's what I'd like to see.  In practice, the standard idiom
is so wide spread that anything else confuses, so despite my
preferences, I write :

    int i ;
    while ( cin >> i )
        ...

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/11
Raw View
Michiel Salters wrote:
....
> if (X *x = dynamic_cast<X *>(y))
> {
>         ;
> } else
> {
>         x;
> }
>
> Another mystery to me is that you read X *x = dynamic_cast<X *>(y) as
> "define some variable if and only if _some_condition_ is true".
> (Emphasis mine). There is no condition in that expression!

According to the C++ standard, a _condition_ can take the form of
    _type-specifier-seq_ _declarator_ = _assignment-expression_

If you don't see a condition, then you aren't parsing it according to
the C++ standard.

> Conditions are <,>,<=,>=,== and !=, after all.

Those are operators, not conditions. Expressions containing those
operators are conditions, but according to the standard, any expression
qualifies as a condition, not just the ones containing conditional
operators.

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/05/11
Raw View
j> ...  One is actually _encouraged_ to write code such as
j>
j>       while((cin >> int c) != EOF){ ...
j>
j> because it improves efficiency to declare a variable where it is
j> initialized.  Removing the ability to initialize variables within
j> conditional statements would actually DETRACT from C++ in addition
j> to the other stated reasons.

A> You probably meant
A>
A>         for(int c; (cin>>c) != EOF; ) { // ...

He probably also meant to use the get() method rather than the >> operator.

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/05/11
Raw View
DT> (I really wish C++ had made it illegal for conditional expressions
DT> to be composed of anything other than boolean expressions. [...])

JdeBP> It did.  A program is ill-formed if the the expression in an
JdeBP>`if' (or `for' or `while') statement cannot be implicitly
JdeBP> converted to `bool'.  See 6.4(4).

JK> Correct.  And then it went and loosened up the syntax by not
JK> requiring an expression at all.

To say that it "loosened up the syntax" is to imply that the above is a
syntactic constraint.  It is not.  One cannot determine on purely syntactic
grounds whether or not an expression can be implicitly converted to `bool'.

In any case, if one looks purely at the syntax of an `if' statement, then one
finds that it was pretty loose to start with, since the expression could be
any expression that one liked.  Given the enormous scope for variation in the
syntax of <expression> that there was already, the syntax of the `if'
statement wasn't really all that "loosened up" by allowing variable
definitions as well as expressions.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/11
Raw View
J=F6rg Barfurth wrote:
>=20
> >>>>>>>>>>>>>>>>>> Urspr=FCngliche Nachricht <<<<<<<<<<<<<<<<<<
>=20
> Am 10.05.00, 04:56:29, schrieb James Kuyper <kuyper@wizard.net> zum The=
ma
> Re: =3D and =3D=3D operators still visually ambiguous:
>=20
> > David R Tribble wrote:
....
> > >     if (TCircle *c =3D dynamic_cast<TCircle *>(shapePtr), c !=3D NU=
LL)
> > >     {
> > >         /* some code */
> > >     }
....
> >The thing inside the if() must be a
>=20
> > _condition_:
> >       _expression_
> >       _type-specifier-seq_ _declarator_ =3D _assignment-expression_
....
> > In other words, it's
> > equivalent to
>=20
> No, because '_expression_ , _assignment-expression_' is not an
> '_assignment-expression_'.

Oops! - I missed that one. It's even worse than I thought.

> > if(TCircle *c =3D (dynamic_cast<TCircle *>(shapePtr), c !=3D NULL) )
> > {
> >       /* some code */
> > }
>=20
> > Which fails horribly for at least six different reasons.
>=20
> Among them, of course, that a 'bool' isn't convertible to a 'TCircle*'

Yes. I started listing all the things that were wrong with that
statement, but gave up, because there were far too many, and it wasn't
fair to David Tribble to list them all; he clearly hadn't intended that
interpretation.

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/05/11
Raw View
"Andrew F. Vesper" <avesper@wn.net> wrote:
> Biju Thomas wrote:
> >   void f ()
> >   {
> >     int a;
> >     int b;
> >     if ( a = g1() ) { /*...*/ }
> >     if ( b = g2() ) { /*...*/ }
> >   }
> >
> > If this is re-written to:
> >
> >   void f ()
> >   {
> >     if ( int a = g1() ) { /*...*/ }
> >     if ( int b = g2() ) { /*...*/ }
> >   }
> >
> > then, the two local variables can share the same storage on
> > the stack.
>
> They can share the same storage on the stack for both examples,
> as long as the compiler can figure out that the effective lifetimes
> are distinct.

That doesn't actually disprove his point, however, since one cannot generalise
your argument from that particular example to all cases.  There are
non-trivial cases where the compiler cannot by itself determine what the
"effective lifetime" of the two objects is and combine their storage (consider
code that takes the address of `a', for example), at which point the explicit
more restrictive scoping of the second form can be used to determine the
lifetime of the storage.

It is also important to consider that the second form is safer (and hence more
desirable) from a maintenance programming perspective.

---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/11
Raw View
In article <3918C6CB.2A64C4C4@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>I'm in the latter; I search backward from the point of use. This is
>partly due to the fact that I'm current required to code according to
>standards that require a comment typically containing about 40 lines of
>documentation. This comment is required to be placed between the '{' at
>the start of a function declaration, and the first line of code in that
>function. I can't defend this requirement, but I do have to code
>according to it. This means that the vi command which goes to the start
>of the function isn't very helpful.

The issue of C Vu (ACCU's base periodical) contains a short article by
Jon Jagger on the subject of comments.  He argues that we should apply
'need to know' and prioritise files so that only the most essential
comments are 'in your face'. Such things as maintenance records etc.
should be stuck at the back of the file.  They are there when you need
them, but do not intrude on the main purpose of the file -- containing
code.

What you relate seems much worse even than the conventions he was
attacking. Anything that separates the body of the code from the
'header' inevitably leads to, at best, wasted time. 40 lines of comment
in such a place must be costing either productivity or quality.


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/05/11
Raw View
David R Tribble <david@tribble.com> writes:
>> There are various opinions about what makes for the most readable
>> code.  The following is an extract from the Java coding conventions
>> document from Sun (which is not always adhered to by Sun employees),
>> which can be applied to C++ programming style:

Francis Glassborow wrote:
[...]
> My rule is:
> Define a variable no sooner than you can initialise it and no later
> than its point of first use.

Unfortunately, that rule is vague enough to cover all schools of
thought, since you can define and initialize a variable anywhere in
C++.  It stands to reason that you can always define and initialize
a variable at the top of a function, even if that initialized value
is just zero.  It also stands to reason that you can't define a
variable after its first use.  These two facts allow a local
variable to be defined anywhere within a function.  (Unless your
point was to be intentionally vague and I just missed it. ;-)

The different schools of thought appear to be:
a) those that like to place all their local variable definitions at
 the top of the function and nowhere else;
b) those that like to have local variables spread throughout the
 function, but always define them at the top of each local
 block/scope in which they are used, i.e., variables are defined
 at the beginning of the smallest scope possible.
c) those that like to define variables immediately before they are
 used, or equivalently, as late as possible in the code.

For-loops are a boundary case in (b), since they can be done in two
ways and still abide by the constraints of (b):

    // (b1)
    int  i;
    for (i = ...) ...

    // (b2)
    for (int i = ...) ...

I must also point out that function arguments are a special case of
local variables, and must be declared at the top of the function.
On the other hand, they can't be initialized, so in that regard they
don't act like local variables.

Examples:

    // Style (a)
    int foo(int a)
    {
        int  b = 0;
        int  i;
        int  j;

        for (i = 0;  i < a;  i++)
        {
            for (j = 0;  j < h[i].size;  j++)
                b += h[i].val * c[j];
        }
        return b;
    }

    // Style (b)
    int foo(int a)
    {
        int  b = 0;
        int  i;

        for (i = 0;  i < a;  i++)
        {
            int  j;

            for (j = 0;  j < h[i].size;  j++)
                b += h[i].val * c[j];
        }
        return b;
    }

    // Style (b)
    int foo(int a)
    {
        int  b = 0;
        for (int i = 0;  i < a;  i++)
        {
            for (int j = 0;  j < h[i].size;  j++)
                b += h[i].val * c[j];
        }
        return b;
    }

For the record, I'm in category (b).

One last comment.  Java disallows anything except expressions of
type boolean for conditional expressions, and there doesn't seem to
be any outcry within the Java programming community that this is an
unreasonable limitation.  I'll leave others to argue whether this
makes Java better or worse than C++...

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/13
Raw View
David R Tribble wrote:
....
> Francis Glassborow wrote:
> [...]
> > My rule is:
> > Define a variable no sooner than you can initialise it and no later
> > than its point of first use.
>
> Unfortunately, that rule is vague enough to cover all schools of
> thought, since you can define and initialize a variable anywhere in
> C++.  It stands to reason that you can always define and initialize
> a variable at the top of a function, even if that initialized value
> is just zero. ...

Not true; zero might not even be a valid initializer for some UDT's.
Many types have (quite properly) no default constructor. For some types,
assignment is an expensive process, so you don't want to waste time
constructing an unused value, just so it can be replaced later by
assignment with a useful value. Your rule forces such discarded
initializations. For a few types there is, quite properly, no accessible
assignment operator, so discarded initialization isn't even an option.

A more precise statement of the rule would be
"Define a variable no sooner than you can initialize it with a value
that may actually be used ...". The ideal, of course, would be to never
initialize it to a value that isn't used, but achieving that ideal would
often make the logic excessively complicated.

> ... It also stands to reason that you can't define a
> variable after its first use.  These two facts allow a local
> variable to be defined anywhere within a function.  (Unless your
> point was to be intentionally vague and I just missed it. ;-)

His intent seems quite clear to me, I have trouble understanding how you
misinterpreted it. I realize that it was imperfectly stated, and if
anyone could sympathize with nit-picking, I'm the one :-). However, the
intent was clear, and your message shows no sign of any awareness of
that intent.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/09
Raw View
AllanW wrote:
>
>   James Kuyper <kuyper@wizard.net> wrote:
> > David R Tribble wrote:
> > ....
> > > This is what compound statement blocks are for - limiting the scope
> > > of inner variables. ...
> >
> > That's what they were for in C90, but not in C99 or C++.
>
> I respectfully disagree.
> Consider the "construction is allocation" paradigm.
>
>     void foo() {
>        ... non-critical setup ...
>        { CriticalSection cs; // Begin critical section
>           ... critical processing ...
>        } // End critical section
>        ... non-critical cleanup ...
>     }
>
> The block controls when cs is destructed.

Perhaps I should have worded that differently. Dave Tribble's comment,
in the context which you dropped, appears to have meant that compound
statement blocks are the ONLY things that should be used to control the
scope of inner variables. Otherwise it wouldn't qualify as a coherent
objection to definitions in for() statements.

What I meant was that in C++ and C99, and unlike C90, there are
additional constructs that are for controlling the scope of an inner
variable. Specifically, for() in both languages, and while(), if(), and
switch() in C++. Unlike Dave Tribble, I don't see anything wrong with
making use of this capability, at least under appropriate circumstances.

Appropriate use of variables defined in the controlling condition of
while(), if(), and switch() statements is inherent in the way those
constructs use the variable - if defining a variable there works, then
it's appropriate to define it there. Appropriate use of variables
defined in a for() statement is more subjective - my own rough criterion
is that defining a variable in the first part of a for() is appropriate
if the variable is used in at least two of the other three parts of that
statement (and nowhere else, but that is another of those self-enforcing
rules).

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/05/09
Raw View
David Tribble:
>> (I really wish C++ had made it illegal for conditional
>> expressions to be composed of anything other than boolean
>> expressions. [...])

Jonathan de Boyne Pollard wrote:
>> It did.  A program is ill-formed if the the expression in an `if'
>> (or `for' or `while') statement cannot be implicitly converted to
>> `bool'.  See 6.4(4).

David R Tribble <david@tribble.com>:
>| That's not what I meant; I meant that I really wish C++ had made it
>| illegal to use expressions with types other than boolean for
>| conditional expressions, and that implicit conversions to boolean
>| were not done for you.  Allowing implicit conversions is just as
>| bad as allowing non-boolean expressions in the first place.

Sebastian Moleski wrote:
> Everynbody has the right to express his wrong opinion. <g>
>
> I don't see how not having an implict type conversion would help me
> with code like the following:
>
> if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
>     /* some code */
> }

What would help with such code is to pull the declaration and
initialization out of the conditional expression.  Imagine the poor
sap who gets to maintain this code, having a difficult time locating
the variable definition.

    TCircle *  c;

    c = dynamic_cast<TCircle *>(shapePtr);
    if (c != NULL)
        ...

This assumes that, like me, you don't like conditional expressions
to be anything more than just conditional expressions.

But, if you absolutely insist on puttin all three semantic operations
(definition, assignment/initialization, test for null) together
into a single statement, you can always do this:

    if (TCircle *c = dynamic_cast<TCircle *>(shapePtr), c != NULL)
    {
        /* some code */
    }

Note the lack of implicit conversion to bool.  Note also that we
don't *ever* need implicit bool conversions in conditional
expressions.

And I agree, everybody has the right to express his wrong opinion. <g>

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: David R Tribble <david@tribble.com>
Date: 2000/05/09
Raw View
AllanW wrote:
>
> jeffturneresq@my-deja.com wrote:
>> ...  One is actually _encouraged_ to write code such as
>>
>>       while((cin >> int c) != EOF){ ...         // [1]
>>
>> because it improves efficiency to declare a variable where it is
>> initialized.  Removing the ability to initialize variables within
>> conditional statements would actually DETRACT from C++ in addition to
>> the other stated reasons.
>
> You probably meant
>
>         for(int c; (cin>>c) != EOF; ) { // ...    // [2]
>

Both of which are obviously clearer than:

    int  c;
    while (cin >> c, c != EOF)            // [A]
        ...

Or even:

    for (int c; cin >> c, c != EOF; )     // [B]
        ...

It's obvious that my code examples [A] and [B] are much, much less
efficient than [1] or [2], and therefore should be considered bad
style.  Efficiency, after all, is the primary concern of good code.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com
http://www.m-w.com/cgi-bin/dictionary?satire

---
[ 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: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/05/09
Raw View
| Sebastian Moleski wrote:
| > Everynbody has the right to express his wrong opinion. <g>
| >
| > I don't see how not having an implict type conversion would help
me
| > with code like the following:
| >
| > if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
| >     /* some code */
| > }
|
| What would help with such code is to pull the declaration and
| initialization out of the conditional expression.  Imagine the poor
| sap who gets to maintain this code, having a difficult time locating
| the variable definition.
|
|     TCircle *  c;
|
|     c = dynamic_cast<TCircle *>(shapePtr);
|     if (c != NULL)
|         ...

This is dead ugly and does not represent what I wanted to express with
my own code above.

| This assumes that, like me, you don't like conditional expressions
| to be anything more than just conditional expressions.
|
| But, if you absolutely insist on puttin all three semantic
operations
| (definition, assignment/initialization, test for null) together
| into a single statement, you can always do this:
|
|     if (TCircle *c = dynamic_cast<TCircle *>(shapePtr), c != NULL)
|     {
|         /* some code */
|     }

This does not look very elegant either. I don't care whether
dynamic_cast returns a NULL pointer, a boolean false, or green cheese.
Saying things like

if (X *x = dynamic_cast<X *>(y))

say that an x should be defined if an y can be dynamically casted to
an X*. There's no apparent reason why I should check for a NULL
pointer even if the standard defines that dynamic_cast returns a NULL
pointer on failure in this case. It just says define some variable if
and only if some condition is true. Testing for NULL won't make the
code more meaningful nor will it enhance readability.

Regards,

--
Sebastian Moleski
----
The Borland C++ Builder bug lists:
http://www.crosswinds.net/~bcbbugs/



---
[ 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: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/05/09
Raw View
Am 09.05.00, 07:30:50, schrieb David R Tribble <david@tribble.com> zum=20
Thema Re: =3D and =3D=3D operators still visually ambiguous:


> David Tribble:
> >> (I really wish C++ had made it illegal for conditional
> >> expressions to be composed of anything other than boolean
> >> expressions. [...])

> Sebastian Moleski wrote:
> > Everynbody has the right to express his wrong opinion. <g>
> >
> > I don't see how not having an implict type conversion would help me
> > with code like the following:
> >
> > if (TCircle *c =3D dynamic_cast<TCircle *>(shapePtr)) {
> >     /* some code */
> > }

> What would help with such code is to pull the declaration and
> initialization out of the conditional expression.  Imagine the poor
> sap who gets to maintain this code, having a difficult time locating
> the variable definition.

>     TCircle *  c;

>     c =3D dynamic_cast<TCircle *>(shapePtr);
>     if (c !=3D NULL)
>         ...

> This assumes that, like me, you don't like conditional expressions
> to be anything more than just conditional expressions.

Except for the dynamic_cast this very much looks like C code. And for=20
good reason C++ (and even C99) permit to do it safer.
Your code:
- Declares an uninitialized pointer, introducing the potential to use it=20
before it is initialized.
- Injects a name into thze outer block, which isn't meaningful outside=20
the conditional statement.
- Potentially introduces a null pointer into the outer block, increasing=20
the chance that some maintenance programmer will dereference it.

IMO the original idiom is far clearer and safer.=20
The meaning of 'c' is immediately obvious when you see its declaration:=20
It points to '*shapePtr' as a TCircle iif shapePtr in fact points to a=20
TCircle. Accordingly there wont be a 'c' if that is not the case.
I agree with Sebastian that in this particular case it is an unimportant=20
detail that dynamic_cast returns NULL to indicate 'failure'.

To make the role of c even clearer I might even change the code to read:
   if (TCircle * const c =3D dynamic_cast<TCircle *>(shapePtr)) {
     /* some code */
   }
In this case the abuse of reassigning c would be impossible.

> But, if you absolutely insist on puttin all three semantic operations
> (definition, assignment/initialization, test for null) together
> into a single statement, you can always do this:

>     if (TCircle *c =3D dynamic_cast<TCircle *>(shapePtr), c !=3D NULL)
>     {
>         /* some code */
>     }

Which is ill-formed. You can have an initialization or an expression in a=
=20
condition, but not both.

> Note the lack of implicit conversion to bool.  Note also that we
> don't *ever* need implicit bool conversions in conditional
> expressions.

Note that this use is special. I agree that implicit conversions to bool=20
should be avoided whenever the meaning of the condition is more clearly=20
expressed by expanding (e.g.) a comparison.
Note also, that my emphasis is in expressing the meaning of the=20
condition. When reading such code I usually don't ponder about the=20
conversions going on behind the scenes. It should usually conform to=20
common idioms to achieve this.
=20
> And I agree, everybody has the right to express his wrong opinion. <g>

Me too <bg>.

-- J=F6rg Barfurth


---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/09
Raw View
David R Tribble wrote:
>
> AllanW wrote:
> >
> > jeffturneresq@my-deja.com wrote:
> >> ...  One is actually _encouraged_ to write code such as
> >>
> >>       while((cin >> int c) != EOF){ ...         // [1]
> >>
> >> because it improves efficiency to declare a variable where it is
> >> initialized.  Removing the ability to initialize variables within
> >> conditional statements would actually DETRACT from C++ in addition to
> >> the other stated reasons.
> >
> > You probably meant
> >
> >         for(int c; (cin>>c) != EOF; ) { // ...    // [2]
> >
>
> Both of which are obviously clearer than:
      {
>     int  c;
>     while (cin >> c, c != EOF)            // [A]
>         ...
      }

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/09
Raw View
David R Tribble wrote:
....
> Sebastian Moleski wrote:
> > Everynbody has the right to express his wrong opinion. <g>
> >
> > I don't see how not having an implict type conversion would help me
> > with code like the following:
> >
> > if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
> >     /* some code */
> > }
>
> What would help with such code is to pull the declaration and
> initialization out of the conditional expression.  Imagine the poor
> sap who gets to maintain this code, having a difficult time locating
> the variable definition.

Yes - it's so difficult looking in places closely related to the actual
use of the variable. It's so much easier to look farther away.

---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/05/10
Raw View
On Tue, 9 May 2000 05:30:50 CST, David R Tribble <david@tribble.com>
wrote:

> David Tribble:
> But, if you absolutely insist on puttin all three semantic operations
> (definition, assignment/initialization, test for null) together
> into a single statement, you can always do this:
>
>     if (TCircle *c = dynamic_cast<TCircle *>(shapePtr), c != NULL)

I don't think so.  Note that the condition may be either a declaration
or an expression, but not both.

> And I agree, everybody has the right to express his wrong opinion. <g>

QED  :)
John

---
[ 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: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@attglobal.net>
Date: 2000/05/10
Raw View
Am 09.05.00, 07:35:30, schrieb David R Tribble <david@tribble.com> zum
Thema Re: = and == operators still visually ambiguous:


> > jeffturneresq@my-deja.com wrote:
> >> ...  One is actually _encouraged_ to write code such as
> >>
> >>       while((cin >> int c) != EOF){ ...         // [1]

Of course this is ill-formed. Some people miss a way to initialize a
variable from a stream.

> > You probably meant
> >
> >         for(int c; (cin>>c) != EOF; ) { // ...    // [2]

Which I dislike as well. I prefer to use 'for' only if all three parts
apply: Initializing loop control, checking the loop condition and
preparing the next round.

> Both of which are obviously clearer than:

I miss some smileys here and below.

>     int  c;
>     while (cin >> c, c != EOF)            // [A]
>         ...
Which is also illegal. I would prefer:

    int c; // though I don't like uninitialized variables :-(
    while(cin >> c)
        // ....

.. which clearly expresses: While '>>' does extract an integer from cin
into c, do ...

> Or even:

>     for (int c; cin >> c, c != EOF; )     // [B]
>         ...

Though I dont really like it, the following would at least compile:
   for (int c; cin >> c; )     // [B]
       ...

But it seems you would prefer:
  for(int c; cin >> c, cin != NULL; ) ...
<g>

Well, actually I suspect your style would be to prefer:
    for(int c; cin >> c, !cin.fail(); )
       ...

or rather
    int c;
    while( cin >> c, !cin.fail() )
        ...

I dislike the comma operator though. I find it a lot harder to read.

And testing for '!cin.fail()' has two sides: It makes the test being
performed more explicit, but it actually hides that we primarily care
about the success of extracting an int, not about the state of the input
stream (although those are obviously connected).

[More consequential would be to do it all separately. Maybe:
    int c;
    for( cin >> c; !cin.fail(); cin >> c) ....
or the version obtained by expanding this for-loop to a while-loop]

> It's obvious that my code examples [A] and [B] are much, much less
> efficient than [1] or [2], and therefore should be considered bad
> style.  Efficiency, after all, is the primary concern of good code.

Although I miss the smiley, I assume we agree that (a) there is no real
difference in efficiency between all these examples, (b) premature
optimization is the root of much evil, (c) readability and
maintainability are usually much more important than local optimizations

---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 2000/05/10
Raw View
On Tue, 9 May 2000 05:35:30 CST, David R Tribble <david@tribble.com>
wrote:

> AllanW wrote:
> > jeffturneresq@my-deja.com wrote:
> >>       while((cin >> int c) != EOF){ ...         // [1]

> >         for(int c; (cin>>c) != EOF; ) { // ...    // [2]

>     int  c;
>     while (cin >> c, c != EOF)            // [A]

>     for (int c; cin >> c, c != EOF; )     // [B]

This discussion does seem a bit silly.  Nothing works.  In the first
two examples, cin>> returns cin which is not likely to be the int EOF
even when converted to (void*)0.  In the second two examples an int
value equal to EOF would stop the loop; however, the input ending or
bad data will allow it to run forever.

Is there a c=cin.get() missing somewhere?  This C stuff really should
be depricated.  :)

John

---
[ 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: Michiel Salters <salters@lucent.com>
Date: 2000/05/10
Raw View
Sebastian Moleski wrote:

> Saying things like

> if (X *x = dynamic_cast<X *>(y))

> say that an x should be defined if an y can be dynamically casted to
> an X*. There's no apparent reason why I should check for a NULL
> pointer even if the standard defines that dynamic_cast returns a NULL
> pointer on failure in this case. It just says define some variable if
> and only if some condition is true. Testing for NULL won't make the
> code more meaningful nor will it enhance readability.

> Regards,
> Sebastian Moleski

Actually x is always defined, even if the condition is false. If
it weren't, the following code would be illegal instead of silly:

if (X *x = dynamic_cast<X *>(y))
{
 ;
} else
{
 x;
}

Another mystery to me is that you read X *x = dynamic_cast<X *>(y) as
"define some variable if and only if _some_condition_ is true".
(Emphasis mine). There is no condition in that expression!
Conditions are <,>,<=,>=,== and !=, after all.

What happens is that if the conditional of an if-statement is a
pointer, NULL is mapped to false and any other pointer to true.
Readability is IMO improved by preferring an explicit test over
this implicit conversion.

Michiel Salters

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/10
Raw View
David R Tribble wrote:
....
> But, if you absolutely insist on puttin all three semantic operations
> (definition, assignment/initialization, test for null) together
> into a single statement, you can always do this:
>
>     if (TCircle *c = dynamic_cast<TCircle *>(shapePtr), c != NULL)
>     {
>         /* some code */
>     }

Problem: I believe that the above code can't legally be parsed the way
you intend. The thing inside the if() must be a

_condition_:
 _expression_
 _type-specifier-seq_ _declarator_ = _assignment-expression_

I believe that you're trying to interpret the _condition_ as an

_expression_:
 _expression_ , _assignment-expression_

But that would require interpreting the definition of 'c' as an
expression, and it isn't. I believe that the above code must be
interpreted as the second kind of _condition_. In other words, it's
equivalent to

if(TCircle *c = (dynamic_cast<TCircle *>(shapePtr), c != NULL) )
{
 /* some code */
}

Which fails horribly for at least six different reasons.

---
[ 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: James Dennett <jdennett@acm.org>
Date: 2000/05/04
Raw View
James Kuyper wrote:
>
> Jonathan de Boyne Pollard wrote:
> >
> > DT> (I really wish C++ had made it illegal for conditional expressions
> > DT> to be composed of anything other than boolean expressions. [...])
> >
> > It did.  A program is ill-formed if the the expression in an `if' (or `for' or
> > `while') statement cannot be implicitly converted to `bool'.  See 6.4(4).
>
> That's not the same as requiring a boolean expression. It allows
> non-boolean expressions that can be implicitily converted to 'bool'.

That hints at the problem: implicit conversion to bool is not a Good
Thing, but
it is a basic aspect of C which has been carried over to C++.  Almost
anything can
be converted to bool (allowing poetic license) -- even the name of a
function,
which is an odd way of writing "true".

I very much doubt that C++ will be changed to disallow the built-in
implicit
conversions to bool: it would break too much existing code.  A shame,
IMO.

-- James Dennett <jdennett@acm.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david@tribble.com>
Date: 2000/05/06
Raw View
David Tribble:
>> (I really wish C++ had made it illegal for conditional expressions
>> to be composed of anything other than boolean expressions. [...])

Jonathan de Boyne Pollard wrote:
> It did.  A program is ill-formed if the the expression in an `if' (or
> `for' or `while') statement cannot be implicitly converted to `bool'.
> See 6.4(4).

That's not what I meant; I meant that I really wish C++ had made it
illegal to use expressions with types other than boolean for
conditional expressions, and that implicit conversions to boolean
were not done for you.  Allowing implicit conversions is just as
bad as allowing non-boolean expressions in the first place.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/05/08
Raw View
David R Tribble <david@tribble.com>:
| David Tribble:
| >> (I really wish C++ had made it illegal for conditional
expressions
| >> to be composed of anything other than boolean expressions. [...])
|
| Jonathan de Boyne Pollard wrote:
| > It did.  A program is ill-formed if the the expression in an `if'
(or
| > `for' or `while') statement cannot be implicitly converted to
`bool'.
| > See 6.4(4).
|
| That's not what I meant; I meant that I really wish C++ had made it
| illegal to use expressions with types other than boolean for
| conditional expressions, and that implicit conversions to boolean
| were not done for you.  Allowing implicit conversions is just as
| bad as allowing non-boolean expressions in the first place.

Everynbody has the right to express his wrong opinion. <g>

I don't see how not having an implict type conversion would help me
with code like the following:

if (TCircle *c = dynamic_cast<TCircle *>(shapePtr)) {
    /* some code */
}

--
Sebastian Moleski
----
The Borland C++ Builder bug lists:
http://www.crosswinds.net/~bcbbugs/



---
[ 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: kanze@gabi-soft.de
Date: 2000/05/08
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  > Generally speaking, a statement should do one, and only one thing.
|>  > A while statement controls a looping construct -- it does NOT
|>  > declare a new variable, nor modify program state in any way.
|>  > Doing so has a definite cost in program readability.  In certain
|>  > cases, doing so may provide other gains -- whether these gains
|>  > offset the cost in readability is an arguable question, but for
|>  > better or worse, idioms like "while ( cin >> whatever )" are
|>  > prevalent to a degree that when one uses anything else, it raises
|>  > questions as to why in the readers mind.

|>  By that argument, you shouldn't be using for() statements. In
|>  typical use they do three things in a single statement, excluding
|>  the controlled statement itself. If the for-init-statement is a
|>  declaration, and the condition is an active one, you might even
|>  consider it to be doing five or more things in one statement. Do you
|>  in fact avoid for() statements?

Taken literally, my argument would also mean no while statements, since
the controlled block is syntactically part of the while statement, and
generally, it will do something.

Obviously, I didn't mean my statement to be taken that literally, and as
you point out (in the part I cut), there is no real formal definition
for a flow statement.  Intuitively, however, the conditional expression
in a while or an if statement -- or a for statement -- controls flow.
As such, having it do anything else in addition is a potential source of
confusion, and has a price with regards to clarity.  How big a price,
and the price of the alternatives, is a matter for debate, and I myself
pointed out a case where the price of the alternatives was such that the
side effects where the best solution.  Avoiding the side effects is,
however, a good general rule, and when there is no particular motivation
to do otherwise, I would recommend following it.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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 <allan_w@my-deja.com>
Date: 2000/05/08
Raw View
  James Kuyper <kuyper@wizard.net> wrote:
> David R Tribble wrote:
> ....
> > This is what compound statement blocks are for - limiting the scope
> > of inner variables. ...
>
> That's what they were for in C90, but not in C99 or C++.

I respectfully disagree.
Consider the "construction is allocation" paradigm.

    void foo() {
       ... non-critical setup ...
       { CriticalSection cs; // Begin critical section
          ... critical processing ...
       } // End critical section
       ... non-critical cleanup ...
    }

The block controls when cs is destructed.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/08
Raw View
In article <39133178.DE30D352@tribble.com>, David R Tribble
<david@tribble.com> writes
>That's not what I meant; I meant that I really wish C++ had made it
>illegal to use expressions with types other than boolean for
>conditional expressions, and that implicit conversions to boolean
>were not done for you.  Allowing implicit conversions is just as
>bad as allowing non-boolean expressions in the first place.

But, IMO, providing implicit conversions from bool to int was a real bad
decision. I know why it was made, but it is an example of why consensus
can lead to worse decisions than straight majority voting.


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: kanze@gabi-soft.de
Date: 2000/05/08
Raw View
David R Tribble <david@tribble.com> writes:

|>  That's not what I meant; I meant that I really wish C++ had made it
|>  illegal to use expressions with types other than boolean for
|>  conditional expressions, and that implicit conversions to boolean
|>  were not done for you.

So did the authors of the bool proposal.  In the original proposal, the
conversions were deprecated, so as to encourage the compiler writers to
generate warnings.  The deprecation didn't get past the committee,
however.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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 <allan_w@my-deja.com>
Date: 2000/05/09
Raw View
jeffturneresq@my-deja.com wrote:
> ...  One is actually _encouraged_ to write code such as
>
>       while((cin >> int c) != EOF){ ...
>
> because it improves efficiency to declare a variable where it is
> initialized.  Removing the ability to initialize variables within
> conditional statements would actually DETRACT from C++ in addition to
> the other stated reasons.

You probably meant

        for(int c; (cin>>c) != EOF; ) { // ...

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Biju Thomas <b.thomas@attglobal.net>
Date: 2000/04/26
Raw View
"Andrew F. Vesper" wrote:
>
> Biju Thomas wrote:
>
> >   void f ()
> >   {
> >     int a;
> >     int b;
> >
> >     if ( a = g1() )
> >     {
> >       //....
> >     }
> >     if ( b = g2() )
> >     {
> >       //....
> >     }
> >   }
> >
> > where there two local variables.
> >
> > If this is re-written to:
> >
> >   void f ()
> >   {
> >     if ( int a = g1() )
> >     {
> >       //...
> >     }
> >     if ( int b = g2() )
> >     {
> >       //...
> >     }
> >   }
> >
> > then, the two local variables can share the same storage on the stack.
>
> They can share the same storage on the stack for both examples,
> as long as the compiler can figure out that the effective lifetimes are
> distinct.
>

For builtin variables, the compiler can do that. (If it is capable of
figuring out that the effective lifetimes of the two variables are
distinct. Doing that may not be easy.) But, for objects with non-trivial
destructors, that is not allowed since the destructors can have
observable side-effects and the objects are required to be destructed at
the end of the containing block.

--
Biju Thomas

---
[ 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: "Sebastian Moleski" <sebmol@gmx.net>
Date: 2000/04/26
Raw View
I often use things like

if (Y *p = dynamic_cast<Y *>(q)) {
...
}

where p is in the scope of the if statement which gets executed only
if the dynamic_cast doesn't fail. Beyond the fact that often use of
dynamic_cast is considered bad design, it's a good place to put an
assignment within a statement.

--
Sebastian Moleski
----
The Borland C++ Builder bug lists:
http://www.crosswinds.net/~bcbbugs/


---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/04/27
Raw View
Sebastian Moleski wrote:
> I often use things like
>
>   if (Y *p = dynamic_cast<Y *>(q)) {
>       ...
>   }
>
> where p is in the scope of the if statement which gets executed only
> if the dynamic_cast doesn't fail. Beyond the fact that often use of
> dynamic_cast is considered bad design, it's a good place to put an
> assignment within a statement.

I think placing declarations ans assignments within conditional
expressions is a Bad Thing, if for no other reason than it makes it
harder to find the definition point of such variables.

(I really wish C++ had made it illegal for conditional expressions
to be composed of anything other than boolean expressions.  C++
borrowed too much of C's syntactical laxness.)

If you really want a separate scope for 'p', why not put braces
around the whole thing to give it its own scope?

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: David R Tribble <david@tribble.com>
Date: 2000/04/27
Raw View
David R Tribble wrote:
>> Burying variable declarations within flow statements does not
>> improve the readability of your program.  In the long run, that
>> kind of programming style costs more in maintenance and time wasted
>> trying to understand the code.

James Kuyper wrote:
> I disagree. There is at least a trade-off between placing declarations
> in a single fixed place, and placing them as close as possible to
> their first use. Both approaches make the declaration easier to find,
> from different points of view.
>
> As a general rule, I think that the scope of an identifier should be
> restricted as tightly as its intended use allows. This minimizes the
> distance between a declaration and its use, increasing the ease of
> mentally connecting the two. It also reduces the opportunities for
> interference with other declarations.

This is what compound statement blocks are for - limiting the scope
of inner variables.  If your function block is small enough, then
placing all the local variable definitions at the top still keeps
them close to their first use.

If the distance (number of lines) is great between the top of the
function and the first use of a variable, then it's fairly likely
that your function is big enough to be split into smaller functions,
or you should consider at least using extra scoping blocks to divide
up your function into logical (more readable) chunks.

Yura Koblents-Mishke wrote:
> I believe you are wrong.
>
> In all block languages, starting from Algol-60, and
> later in PL/1, Pascal and C, it was practically always
> better to put local variable(s) in local scope: [...]

We are both saying the same thing.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: James Kuyper <kuyper@wizard.net>
Date: 2000/04/28
Raw View
David R Tribble wrote:
....
> This is what compound statement blocks are for - limiting the scope
> of inner variables. ...

That's what they were for in C90, but not in C99 or C++.

> ...  If your function block is small enough, then
> placing all the local variable definitions at the top still keeps
> them close to their first use.
>
> If the distance (number of lines) is great between the top of the
> function and the first use of a variable, then it's fairly likely
> that your function is big enough to be split into smaller functions,
> or you should consider at least using extra scoping blocks to divide
> up your function into logical (more readable) chunks.

I can agree with that. Well-designed C++ code tends to be made up of
large numbers of small member functions, rather than a few large
ordinary functions. However, when the distance is small, it doesn't make
much difference whether a variable is defined at first use or at the top
of a compound statement. Given that C++ explicitly allows definition of
variables in the outer portion of if(), while(), switch(), and for()
statements, I see no point in uglifying my code by using an enclosing
block instead of taking advantage of that feature.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/04/28
Raw View
David R Tribble wrote:
>
> Sebastian Moleski wrote:
> > I often use things like
> >
> >   if (Y *p = dynamic_cast<Y *>(q)) {
> >       ...
> >   }
> >
> > where p is in the scope of the if statement which gets executed only
> > if the dynamic_cast doesn't fail. Beyond the fact that often use of
> > dynamic_cast is considered bad design, it's a good place to put an
> > assignment within a statement.
>
> I think placing declarations ans assignments within conditional
> expressions is a Bad Thing, if for no other reason than it makes it
> harder to find the definition point of such variables.

The use of 'p' is closely associated with the condition; you wouldn't
want to use it in any way unless the condition is true. I think it's a
reasonable place to look for the definition.

....
> If you really want a separate scope for 'p', why not put braces
> around the whole thing to give it its own scope?

Because that's unnecessarily complicated and ugly, and the current rules
allow a cleaner syntax for expressing the same idea.

---
[ 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: kanze@gabi-soft.de
Date: 2000/05/02
Raw View
Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net> writes:

|>  DT> (I really wish C++ had made it illegal for conditional expression=
s
|>  DT> to be composed of anything other than boolean expressions. [...])

|>  It did.  A program is ill-formed if the the expression in an `if'
|>  (or `for' or `while') statement cannot be implicitly converted to
|>  `bool'.  See 6.4(4).

Correct.  And then it went and loosened up the syntax by not requiring
an expression at all.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: kanze@gabi-soft.de
Date: 2000/05/02
Raw View
David R Tribble <david@tribble.com> writes:

|>  Biju Thomas wrote:
|>  >>   void f ()
|>  >>   {
|>  >>     int a;
|>  >>     int b;

|>  >>     if ( a =3D g1() )
|>  >>     {
|>  >>       //....
|>  >>     }
|>  >>     if ( b =3D g2() )
|>  >>     {
|>  >>       //....
|>  >>     }
|>  >>   }

|>  >> where there two local variables.
|>  >>

|>  >>
|>  >>   void f ()
|>  >>   {
|>  >>     if ( int a =3D g1() )
|>  >>     {
|>  >>       //...
|>  >>     }
|>  >>     if ( int b =3D g2() )
|>  >>     {
|>  >>       //...
|>  >>     }
|>  >>   }

|>  >> then, the two local variables can share the same storage on the
|>  >> stack.

|>  Andrew F. Vesper wrote:
|>  > They can share the same storage on the stack for both examples,
|>  > as long as the compiler can figure out that the effective lifetimes
|>  > are distinct.

|>  Right.  Most of the time, the compiler can do a better job of
|>  optimizing than you can.  You should write your code so that it's
|>  understandable and easy to maintain, not so that it might save a
|>  few cycles (90% of which won't be noticed anyway).

The same storage isn't really the issue.  I don't like the style either,
but the argument for it has nothing to do with storage.  The argument
for it is that it is impossible to access an instance of a or b that
hasn't been initialized correctly without getting a compiler error.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/05/02
Raw View
kanze@gabi-soft.de wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
....
> |>  I disagree. There is at least a trade-off between placing declarations
> |>  in a single fixed place, and placing them as close as possible to their
> |>  first use. Both approaches make the declaration easier to find, from
> |>  different points of view.
>
> Agreed.  But what does this have to do with burying a variable
> declaration within a flow statement?

I'm not entirely clear what you mean by a flow statement. It's not a
defined term within the C++ grammar. "if(condition) statement" is a
selection statement, but the whole thing is a selection statement,
including the (typically compound) statement controlled by the
condition. Are you saying that you also don't believe in "burying a
variable declaration" within the controlled statement? I'm not
challenging that choice of coding style, I just want to verify whether
this is what you mean.

> Generally speaking, a statement should do one, and only one thing.  A
> while statement controls a looping construct -- it does NOT declare a
> new variable, nor modify program state in any way.  Doing so has a
> definite cost in program readability.  In certain cases, doing so may
> provide other gains -- whether these gains offset the cost in
> readability is an arguable question, but for better or worse, idioms
> like "while ( cin >> whatever )" are prevalent to a degree that when one
> uses anything else, it raises questions as to why in the readers mind.

By that argument, you shouldn't be using for() statements. In typical
use they do three things in a single statement, excluding the controlled
statement itself. If the for-init-statement is a declaration, and the
condition is an active one, you might even consider it to be doing five
or more things in one statement. Do you in fact avoid for() statements?

---
[ 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: Jonathan de Boyne Pollard <J.deBoynePollard@tesco.net>
Date: 2000/04/29
Raw View
DT> (I really wish C++ had made it illegal for conditional expressions
DT> to be composed of anything other than boolean expressions. [...])

It did.  A program is ill-formed if the the expression in an `if' (or `for' or
`while') statement cannot be implicitly converted to `bool'.  See 6.4(4).

DT> If you really want a separate scope for 'p', why not put braces
DT> around the whole thing to give it its own scope?

Because compared to the syntax under discussion it is cumbersome and
introduces an extra level of indentation and an extra closing brace, and is
prone to error as a consequence.

---
[ 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: James Kuyper <kuyper@wizard.net>
Date: 2000/04/30
Raw View
Jonathan de Boyne Pollard wrote:
>
> DT> (I really wish C++ had made it illegal for conditional expressions
> DT> to be composed of anything other than boolean expressions. [...])
>
> It did.  A program is ill-formed if the the expression in an `if' (or `for' or
> `while') statement cannot be implicitly converted to `bool'.  See 6.4(4).

That's not the same as requiring a boolean expression. It allows
non-boolean expressions that can be implicitily converted to 'bool'.

---
[ 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: kanze@gabi-soft.de
Date: 2000/05/01
Raw View
James Kuyper <kuyper@wizard.net> writes:

|>  > Burying variable declarations within flow statements does not
|>  > improve the readability of your program.  In the long run, that
|>  > kind of programming style costs more in maintenance and time wasted
|>  > trying to understand the code.

|>  I disagree. There is at least a trade-off between placing declaration=
s
|>  in a single fixed place, and placing them as close as possible to the=
ir
|>  first use. Both approaches make the declaration easier to find, from
|>  different points of view.

Agreed.  But what does this have to do with burying a variable
declaration within a flow statement?

Generally speaking, a statement should do one, and only one thing.  A
while statement controls a looping construct -- it does NOT declare a
new variable, nor modify program state in any way.  Doing so has a
definite cost in program readability.  In certain cases, doing so may
provide other gains -- whether these gains offset the cost in
readability is an arguable question, but for better or worse, idioms
like "while ( cin >> whatever )" are prevalent to a degree that when one
uses anything else, it raises questions as to why in the readers mind.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/04/21
Raw View
Biju Thomas wrote:
>>   void f ()
>>   {
>>     int a;
>>     int b;
>>
>>     if ( a = g1() )
>>     {
>>       //....
>>     }
>>     if ( b = g2() )
>>     {
>>       //....
>>     }
>>   }
>>
>> where there two local variables.
>>
>> If this is re-written to:
>>
>>   void f ()
>>   {
>>     if ( int a = g1() )
>>     {
>>       //...
>>     }
>>     if ( int b = g2() )
>>     {
>>       //...
>>     }
>>   }
>>
>> then, the two local variables can share the same storage on the
>> stack.

Andrew F. Vesper wrote:
> They can share the same storage on the stack for both examples,
> as long as the compiler can figure out that the effective lifetimes
> are distinct.

Right.  Most of the time, the compiler can do a better job of
optimizing than you can.  You should write your code so that it's
understandable and easy to maintain, not so that it might save a
few cycles (90% of which won't be noticed anyway).

Burying variable declarations within flow statements does not
improve the readability of your program.  In the long run, that
kind of programming style costs more in maintenance and time wasted
trying to understand the code.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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: James Kuyper <kuyper@wizard.net>
Date: 2000/04/22
Raw View
David R Tribble wrote:
>
> Biju Thomas wrote:
....
> >>   void f ()
> >>   {
> >>     if ( int a = g1() )
> >>     {
> >>       //...
> >>     }
> >>     if ( int b = g2() )
> >>     {
> >>       //...
> >>     }
> >>   }
...
> Burying variable declarations within flow statements does not
> improve the readability of your program.  In the long run, that
> kind of programming style costs more in maintenance and time wasted
> trying to understand the code.

I disagree. There is at least a trade-off between placing declarations
in a single fixed place, and placing them as close as possible to their
first use. Both approaches make the declaration easier to find, from
different points of view.

As a general rule, I think that the scope of an identifier should be
restricted as tightly as its intended use allows. This minimizes the
distance between a declaration and its use, increasing the ease of
mentally connecting the two. It also reduces the opportunities for
interference with other declarations.

While it doesn't come up in this case, because late declaration often
allows the definition to include the initialization, it frequently
allows the object to be declared const, with all the attendent safety
advantages in type checking.

---
[ 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: Yura Koblents-Mishke <yura@concentric.net>
Date: 2000/04/24
Raw View

David R Tribble wrote:
>
> Biju Thomas wrote:
> >>   void f ()
> >>   {
> >>     int a;
> >>     int b;
> >>
> >>     if ( a = g1() )
> >>     {
> >>       //....
> >>     }
> >>     if ( b = g2() )
> >>     {
> >>       //....
> >>     }
> >>   }
> >>
> >> where there two local variables.
> >>
> >> If this is re-written to:
> >>
> >>   void f ()
> >>   {
> >>     if ( int a = g1() )
> >>     {
> >>       //...
> >>     }
> >>     if ( int b = g2() )
> >>     {
> >>       //...
> >>     }
> >>   }
> >>
> >> then, the two local variables can share the same storage on the
> >> stack.
>
> Andrew F. Vesper wrote:
> > They can share the same storage on the stack for both examples,
> > as long as the compiler can figure out that the effective lifetimes
> > are distinct.
>
> Right.  Most of the time, the compiler can do a better job of
> optimizing than you can.  You should write your code so that it's
> understandable and easy to maintain, not so that it might save a
> few cycles (90% of which won't be noticed anyway).
>
> Burying variable declarations within flow statements does not
> improve the readability of your program.  In the long run, that
> kind of programming style costs more in maintenance and time wasted
> trying to understand the code.
[snip]

I believe you are wrong.

In all block languages, starting from Algol-60, and
later in PL/1, Pascal and C, it was practically always
better to put local variable(s) in local scope:

void f () {
  { int a;
    if ( a = g1() )  {
      //...
    }
  } // scope for a;

  { int b;
    if ( b = g2() ) {
      //...
    }
  } // scope for b;
}

because this automatically eliminates all sorts of
errors related with intentional (space optimization)
and unintentional (with simple and natural identifiers,
e.g. i or j) re-use of these variables. The secondary
benefit is ease of maintenance: you have to to check
entries of id in one block, not in a whole function,
and sometimes the function is very long. Currently it
is unusual to optimize away one int variable (with
exception of embedded applications., standard libraries
and other high volume programs, the MS products being
exception to exception), but would the variable a and b
be large objects, e.g. 3-dimensional matrices
100x100x100, the space consideration is still
important. And usually it is easier to initialize a
variable if it is local:


void f () {
  { int a = g1();
    if ( a )  {
      //...
    }
  } // scope for a;

  { int b = g2();
    if ( b ) {
      //...
    }
  } // scope for b;
}

The C++ constructs only helps implement the old
practice.

---
[ 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 <allan_w@my-deja.com>
Date: 2000/04/19
Raw View
In article <38F26281.3D98650D@sensor.com>,
  Ron Natalie <ron@sensor.com> wrote:
>
>
> AllanW wrote:
>
> > > a[0] = 1;
> >
> > This is not an assignment within an expression.
>
> You've lost me.  "a[0] = 1" is an expression.  It has an assignment
> in it.

    a[0] = 1;

is an expression, which is a statement. Specifically, it is an
assignment expression.

> > If C++ had
> > assignment statements this would still be valid. This does
> > have an expression (a[0]) within an assignment; perhaps
> > that's what you meant.
>
> C++ doesn't have assignemnt statements

Right...

> it does have expression
> statepemnts which are expressions with semicolons on the end.

That's true. I'll assume that you are not trying to difficult,
but I'm afraid I'm missing your point.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Biju Thomas <b.thomas@attglobal.net>
Date: 2000/04/20
Raw View
Greg Comeau wrote:
>
> In article <8dfa6h$qs4$1@nnrp1.deja.com> jeffturneresq@my-deja.com writes:
> >
> >because it improves efficiency to declare a variable where it is
> >initialized.
>
> Unless you are talking about say programmer productivity,
> there is no such inherent improvement.
>

I am not sure if any compiler does such an improvement, but, I think it
is definitely possible.

Consider the case:

  void f ()
  {
    int a;
    int b;

    if ( a = g1() )
    {
      //....
    }
    if ( b = g2() )
    {
      //....
    }
  }

where there two local variables.

If this is re-written to:

  void f ()
  {
    if ( int a = g1() )
    {
      //...
    }
    if ( int b = g2() )
    {
      //...
    }
  }

then, the two local variables can share the same storage on the stack.

--
Biju Thomas

---
[ 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: "Andrew F. Vesper" <avesper@wn.net>
Date: 2000/04/21
Raw View
Biju Thomas wrote:

>   void f ()
>   {
>     int a;
>     int b;
>
>     if ( a = g1() )
>     {
>       //....
>     }
>     if ( b = g2() )
>     {
>       //....
>     }
>   }
>
> where there two local variables.
>
> If this is re-written to:
>
>   void f ()
>   {
>     if ( int a = g1() )
>     {
>       //...
>     }
>     if ( int b = g2() )
>     {
>       //...
>     }
>   }
>
> then, the two local variables can share the same storage on the stack.

They can share the same storage on the stack for both examples,
as long as the compiler can figure out that the effective lifetimes are
distinct.


--
Andy V (OpenGL Alpha Geek)
"In order to make progress, one must leave the door to the unknown ajar."
Richard P. Feynman, quoted by Jagdish Mehra in _The Beat of a Different Drum_.

Paul Martz's OpenGL FAQ: http://www.frii.com/~martz/oglfaq


---
[ 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: jeffturneresq@my-deja.com
Date: 2000/04/18
Raw View
In article <8asod0$lh1$1@sun27.hrz.tu-darmstadt.de>,
  meixner@rbg.informatik.tu-darmstadt.de (Matthias Meixner) wrote:

> It is common practive to have assignments in expressions, e.g.
>
>     if(fp=fopen(filename,"R")) { ....
>
>     while((c=getchar())!=EOF) { ...
>
>     etc.

   I'd like to expand on this a bit.  One is actually _encouraged_ to
write code such as

      while((cin >> int c) != EOF){ ...

because it improves efficiency to declare a variable where it is
initialized.  Removing the ability to initialize variables within
conditional statements would actually DETRACT from C++ in addition to
the other stated reasons.

> Therefore this change would break tons of existing code and is
> therefore not acceptable.
>
> - Matthias Meixner

--Jeff Turner
using std::disclaimers



Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: comeau@panix.com (Greg Comeau)
Date: 2000/04/18
Raw View
In article <8dfa6h$qs4$1@nnrp1.deja.com> jeffturneresq@my-deja.com writes:
>In article <8asod0$lh1$1@sun27.hrz.tu-darmstadt.de>,
>  meixner@rbg.informatik.tu-darmstadt.de (Matthias Meixner) wrote:
>> It is common practive to have assignments in expressions, e.g.
>>
>>     if(fp=fopen(filename,"R")) { ....
>>
>>     while((c=getchar())!=EOF) { ...
>>
>>     etc.
>
>   I'd like to expand on this a bit.  One is actually _encouraged_ to
>write code such as
>
>      while((cin >> int c) != EOF){ ...

But that's not allowed. (Am I missing your point?)

>because it improves efficiency to declare a variable where it is
>initialized.

Unless you are talking about say programmer productivity,
there is no such inherent improvement.

- Greg
--
Comeau Computing, Producers of Comeau C/C++ 4.2.42 (4.2.43 BETA starting)
Try Comeau C++ online at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.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: James Dennett <jdennett@acm.org>
Date: 2000/04/13
Raw View
Ron Natalie wrote:
>
> AllanW wrote:
>
> > > a[0] = 1;
> >
> > This is not an assignment within an expression.
>
> You've lost me.  "a[0] = 1" is an expression.  It has an assignment
> in it.

I think it might be more precise to say that the assignment is not a
proper sub-expression, rather than saying that "this is not an
assignment within an expression."  In the example, the assignment *is*
the expression, it is not nested *within* the expression.

> > If C++ had
> > assignment statements this would still be valid. This does
> > have an expression (a[0]) within an assignment; perhaps
> > that's what you meant.
>
> C++ doesn't have assignemnt statements, it does have expression
> statepemnts which are expressions with semicolons on the end.

C++ may not define the term "assignment statement," but there are
statements which do assignment (and don't have any other side effects),
so in the absence of language lawyers it would be reasonable to term
them "assignment statements."

The quirk of C++ relative to most languages is that it does indeed
consider assignment to be an expression with a value, so that
assignments
can be nested within other expressions.  It's a technique which has
power
and danger, and we won't get agreement as to whether the power justifies
the risk.  Nice compilers might want to offer the option to warn for use
of an assignment expression as a subexpression, but it *does* have uses
(even if they are controversial) and is in widespread use in current
code,
so there's no way that the C++ Standard will be changed to ban it in the
foreseeable future.

-- James Dennett <jdennett@acm.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/04/13
Raw View
Ron Natalie <ron@sensor.com> writes:

|>  AllanW wrote:

|>  > > a[0] = 1;

|>  > This is not an assignment within an expression.

|>  You've lost me.  "a[0] = 1" is an expression.  It has an assignment
|>  in it.

I believe that the proposal was to eliminate assignment within an
expression, and create assignment statements.  If this were done, this
statement would still be legal, because it would be an assignment
statement.

IMHO, it is obvious that this *would* have been a better solution for
C.  But it seems even more obvious to me that it is far too late now to
consider it.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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 <allan_w@my-deja.com>
Date: 2000/04/11
Raw View
  Paul Black <paul.black@oxsemi.com> wrote:
> ...disallowing assignment within expressions is a
> problem:

It can be, especially for legacy programs.

> a[0] = 1;

This is not an assignment within an expression. If C++ had
assignment statements this would still be valid. This does
have an expression (a[0]) within an assignment; perhaps
that's what you meant.

Here is an assignment within an expressions:

    a[i=0] = 1;

Personally, I sometimes do this when it makes my program
more brief without sacrificing clarity. This is fairly
rare for me, so I might not miss it if I couldn't do it
anymore. But I would hate to break the programs where I've
already done it.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Ron Natalie <ron@sensor.com>
Date: 2000/04/12
Raw View

AllanW wrote:

> > a[0] = 1;
>
> This is not an assignment within an expression.

You've lost me.  "a[0] = 1" is an expression.  It has an assignment
in it.

> If C++ had
> assignment statements this would still be valid. This does
> have an expression (a[0]) within an assignment; perhaps
> that's what you meant.

C++ doesn't have assignemnt statements, it does have expression
statepemnts which are expressions with semicolons on the end.

---
[ 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: Andreas Scherer <as@mitgmbh.de>
Date: 2000/04/01
Raw View
Mike Austin wrote:
>
> Everybody knows the "while ( i = 10 )" syntactical anomaly :),

In our internal programmer's guide we suggest that it is preferable to
place a non-modifiable element on the left side of an equality test.

   while ( 10 = i ) ...

is illegal and yields a compiler error and

   while ( 10 == i ) ...

is syntactically correct _and_ safe.  Of course, the case of _two_
modifiable elements is left to the programmer as an exercise.

> but you can also enter "i == 10" on a line by itself, which looks very
> odd to veteran programmers but looks suspiciously like assignment to a
> novice.

So? -- gcc and vc warn about this "statement without effect".

> I understand that Java does not allow assignment within expressions.
> Is this unacceptable to C++ programmers to be entered into the
> language?

Certainly not.

--
Andreas

---
[ 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: kanze@gabi-soft.de
Date: 2000/03/28
Raw View
Mike Austin <m.austin@chopme-ix.netcom.com> writes:

|>  Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
|>  can also enter "i == 10" on a line by itself, which looks very odd to
|>  veteran programmers but looks suspiciously like assignment to a novice.
|>  I understand that Java does not allow assignment within expressions.

You understand wrong.  Java is exactly like C++ in this regard.  The
only difference is that integral types don't automatically convert to
boolean, so "while ( i = 10 )" has a type mismatch.  (But "i == 10 ;"
is fully legal.)

|>  Is
|>  this unacceptable to C++ programmers to be entered into the language?
|>  If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
|>  "equals" as can be used now is better.  Comments?

It would probably have been better if the language had been so designed
from the start, but it's at least 20 years too late to change now.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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: Mike Austin <m.austin@chopme-ix.netcom.com>
Date: 2000/03/17
Raw View
Hello all,

Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
can also enter "i == 10" on a line by itself, which looks very odd to
veteran programmers but looks suspiciously like assignment to a novice.
I understand that Java does not allow assignment within expressions.  Is
this unacceptable to C++ programmers to be entered into the language?
If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
"equals" as can be used now is better.  Comments?

Mike

---
[ 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: "TiTi" <cenTipod@anTi.com>
Date: 2000/03/18
Raw View
> Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
> can also enter "i == 10" on a line by itself, which looks very odd to
> veteran programmers but looks suspiciously like assignment to a novice.
> I understand that Java does not allow assignment within expressions.  Is
> this unacceptable to C++ programmers to be entered into the language?
> If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
> "equals" as can be used now is better.  Comments?




Another example (an oddtiti) is the following:


    unsigned int i = 6;
    i;


This is also legal and may look redundant, but ... the following function


    void fn( unsigned int i, unsigned j)
    {}


may result in warnings ( variables not used ). To avoid this one can put:

    void fn( unsigned int i, unsigned j)
    {
        i;
        j;
    }


Other than that, statements like

        bool succeeds;
        bool fn();

        if( succeeds = fn () )
        { /*...*/} else {/*...*/}

can be useful and more readable (although some may argue with that).
Otherwise, one would have to write:

    if( fn() )
    {
        succeeds = true;
        // ...
    }
    else
    {
        succeeds = false;
        // ...
    }




TiTi


---
[ 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: Ron Natalie <ron@sensor.com>
Date: 2000/03/18
Raw View
If you want to see more fun, here are some other mistakes
I've made:

 if(foo); {
    ...
 }

Always executes the stuff in the block becasue the if only has a null
statement.  And this one:

 if(foo) {
    ...
 } {
    ...
 }

Note the lack of else, which means the second block is always executed.
This braindamage came from when I was switching back and forth betwen
C and PostScript whose ifelse format has no 'else' keyword between the
blocks.

---
[ 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: Jack Klein <jackklein@att.net>
Date: 2000/03/18
Raw View
On Fri, 17 Mar 2000 17:02:33 CST, Mike Austin
<m.austin@chopme-ix.netcom.com> wrote in comp.std.c++:

> Hello all,
>
> Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
> can also enter "i == 10" on a line by itself, which looks very odd to
> veteran programmers but looks suspiciously like assignment to a novice.
> I understand that Java does not allow assignment within expressions.  Is
> this unacceptable to C++ programmers to be entered into the language?
> If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
> "equals" as can be used now is better.  Comments?
>
> Mike

Just a thought...

This would break every C++ program ever written.  And of course, it
would destroy what C compatibility there is.

Jack Klein
--
Home: http://jackklein.home.att.net

---
[ 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: meixner@rbg.informatik.tu-darmstadt.de (Matthias Meixner)
Date: 2000/03/18
Raw View
Mike Austin (m.austin@chopme-ix.netcom.com) wrote:
: Hello all,
:
: Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
: can also enter "i == 10" on a line by itself, which looks very odd to
: veteran programmers but looks suspiciously like assignment to a novice.
: I understand that Java does not allow assignment within expressions.  Is
: this unacceptable to C++ programmers to be entered into the language?
: If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
: "equals" as can be used now is better.  Comments?

It is common practive to have assignments in expressions, e.g.

    if(fp=fopen(filename,"R")) { ....

    while((c=getchar())!=EOF) { ...

    etc.

Therefore this change would break tons of existing code and is therefore
not acceptable.

- Matthias Meixner

--
Matthias Meixner                   meixner@rbg.informatik.tu-darmstadt.de
Technische Universit   t Darmstadt
Rechnerbetriebsgruppe                          Telefon (+49) 6151 16 6670
Wilhelminenstra   e 7, D-64283 Darmstadt, Germany    Fax (+49) 6151 16 4701


---
[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/03/18
Raw View
Mike Austin <m.austin@chopme-ix.netcom.com> writes:

>Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
>can also enter "i == 10" on a line by itself, which looks very odd to
>veteran programmers but looks suspiciously like assignment to a novice.
>I understand that Java does not allow assignment within expressions.  Is
>this unacceptable to C++ programmers to be entered into the language?
>If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
>"equals" as can be used now is better.  Comments?

A good compiler can warn about both of these.

fjh$ g++ -Wall -c foo.c
foo.c: In function `int main()':
foo.c:3: warning: suggest parentheses around assignment used as truth value
foo.c:6: warning: statement with no effect

The C++ standard does not require such warnings, so this is a quality
of implementation issue.  But I would strongly recommend against
using an implementation that does not have good warnings.

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






Author: Paul Black <paul.black@oxsemi.com>
Date: 2000/03/18
Raw View
Mike Austin <m.austin@chopme-ix.netcom.com> wrote:
> Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
> can also enter "i == 10" on a line by itself, which looks very odd to
> veteran programmers but looks suspiciously like assignment to a novice.
> I understand that Java does not allow assignment within expressions.  Is
> this unacceptable to C++ programmers to be entered into the language?
> If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
> "equals" as can be used now is better.  Comments?

Turn up the warnings on your compiler?

paul@vienna> cat > a.cxx
int F(int i)
{
    i == 10;

    return (i);
}
paul@vienna> g++ -c -Wall a.cxx
a.cxx: In function `int F(int)':
a.cxx:3: warning: statement with no effect

It should be noted that disallowing assignment within expressions is a
problem:
a[0] = 1;

Paul

---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/03/18
Raw View
In article <38D1C501.B5E19474@chopme-ix.netcom.com>, Mike Austin
<m.austin@chopme-ix.netcom.com> writes
>Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
>can also enter "i == 10" on a line by itself, which looks very odd to
>veteran programmers but looks suspiciously like assignment to a novice.
>I understand that Java does not allow assignment within expressions.  Is
>this unacceptable to C++ programmers to be entered into the language?
>If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
>"equals" as can be used now is better.  Comments?

Good environments warn you of assignments in control expressions, really
good ones also warn you of code that does nothing. Changing the rules
requires a change to the grammar that is so fundamental that it would
probably invalidate every existing program (above pure novice level).


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/03/18
Raw View
"TiTi" <cenTipod@anTi.com> writes:

>Another example (an oddtiti) is the following:
>
>    unsigned int i = 6;
>    i;

A good compiler will warn about that one too.

>This is also legal and may look redundant, but ... the following function
>
>    void fn( unsigned int i, unsigned j)
>    {}
>
>may result in warnings ( variables not used ). To avoid this one can put:
>
>    void fn( unsigned int i, unsigned j)
>    {
>        i;
>        j;
>    }

The C++ standard lets you omit the name of an argument which is unused.
This supports a different way of supressing warnings about unused arguments:

 void fn( unsigned int /* i */, unsigned /* j */)
 {}

This approach, which was pioneered by the original Cfront C++ compiler,
is a better approach, since the approach that you suggest would avoid the
warnings about unused arguments, but would (in a good compiler) also result in
warnings about the statements `i;' and `j;' having no effect.

>Other than that, statements like
>
>        bool succeeds;
>        bool fn();
>
>        if( succeeds = fn () )
>        { /*...*/} else {/*...*/}
>
>can be useful and more readable (although some may argue with that).
>Otherwise, one would have to write:
>
>    if( fn() )
>    {
>        succeeds = true;
>        // ...
>    }
>    else
>    {
>        succeeds = false;
>        // ...
>    }

Indeed such statements are useful, but you can easily write them in
only a very slightly modified fashion which avoids the warnings.
For example, GNU C++ will not warn if such assignments are in an additional
pair of parentheses,

        if ((succeeds = fn ()))

and both GNU C++ and Borland C++ will not warn if you
add a comparison against false:

 if ((succeeds = fn()) != false)

Again, this is a quality of implementation issue, but implementations
which have good warnings do exist, so I don't really see any need to
change the language standard.

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






Author: Mike Austin <m.austin@chopme-ix.netcom.com>
Date: 2000/03/21
Raw View
Everybody has expressed valid concerns.  I assume in some compilers you can
turn warnings into errors - that would help.

Although valid:
  while( ch = getchar() != 'q' ) { doit( ch ); }
why not almost the same encapsulated:
  while( file.getchar() != 'q' ) { doit( file.char() ); }
This is just psuedo code, not iostream in particular.

  if( succeeds = fn () )
    { cout << succeeded } else { /*...*/ }
can be simple written as:
  if( obj.fn() )
    { cout << obj.succeeded() } else { /*...*/ }
(Not getting into speed optimization, compile time, etc.)

We are in a C++ newsgroup and not C correct?


Mike

---
[ 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: 2000/03/21
Raw View
Mike Austin wrote:
>
> Everybody has expressed valid concerns.  I assume in some compilers you can
> turn warnings into errors - that would help.
>
> Although valid:
>   while( ch = getchar() != 'q' ) { doit( ch ); }
> why not almost the same encapsulated:
>   while( file.getchar() != 'q' ) { doit( file.char() ); }
> This is just psuedo code, not iostream in particular.

However, this is iostream:

while (file.peek() != 'q') { doit(file.get()); }

[...]

---
[ 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: David R Tribble <david@tribble.com>
Date: 2000/03/22
Raw View
Mike Austin wrote:
> Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
> can also enter "i == 10" on a line by itself, which looks very odd to
> veteran programmers but looks suspiciously like assignment to a
> novice.  I understand that Java does not allow assignment within
> expressions.  Is this unacceptable to C++ programmers to be entered
> into the language?  If it eliminates bugs I don't think so.  Even
> using, god forbid, ":=" or "equals" as can be used now is better.
> Comments?

Disallowing '=' within conditional-expressions would break too much
code, however distasteful anyone thinks that such code is.  A lot
of such code is also the result of macro expansion.  Alas.

Some programmers use EQ nad NE macros instead of == and !=, but
this reeks too much of FORTRAN.

I belong to the school of thought that abhors using assignment within
conditional expressions.  In most cases, there are better
alternatives, to wit:

    if (a = b) ...   // bad

    a = b;           // good
    if (a) ...

    while ((c = getc()) != EOF) ...    // bad

    while (c = getc(), c != EOF) ...   // good

Of course, I still get burned with the occasional unintentional typo,
where I substitute '=' for '==' or visa versa.

The trouble with ':=' is that it requires a shift/unshift while
typing on most keyboards, which is awkward.  Other sequences are
just as bad (e.g., <-).

-- David R. Tribble, david@tribble.com, http://david.tribble.com --
Opinions expressed about programming style are my own.

---
[ 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: Jerry Coffin <jcoffin@taeus.com>
Date: 2000/03/23
Raw View
In article <38D1C501.B5E19474@chopme-ix.netcom.com>, m.austin@chopme-
ix.netcom.com says...
> Hello all,
>
> Everybody knows the "while ( i = 10 )" syntactical anomaly :), but you
> can also enter "i == 10" on a line by itself, which looks very odd to
> veteran programmers but looks suspiciously like assignment to a novice.
> I understand that Java does not allow assignment within expressions.  Is
> this unacceptable to C++ programmers to be entered into the language?
> If it eliminates bugs I don't think so.  Even using, god forbid, ":=" or
> "equals" as can be used now is better.  Comments?

This might be a nice idea, but it'd break so much existing code that
I doubt it can be given serious consideration.  Worse yet, there are
lots of things that really can't be done nearly as conveniently
without it -- for example, a LOT of well written code uses things
like while-loops that do both an assignment and a comparison.  In
many cases it's MUCH more difficult to ensure correct behavior if you
don't allow this.

In short, it's not a good thing to do, and it probably couldn't be
done even if it was.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

---
[ 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              ]