Hello list members.

Some of you may have suspected that I am no longer
subscribed to Team-Ada, which is true, but I am still
involved with Ada. Ada advocacy too.

In a chiefly C++ forum I was recently arguing against coding
conditions in C in the form (lvalue==rvalue) lest they
accidentally end up being (lvalue=rvalue). To prevent
compiling in C of a malformed condition, I was
advocating in particular writing (rvalue==lvalue). Against
my case were protests that the effort in thinking of
putting the constant on the left could be spent instead
checking that the operator is indeed the equality
operator, and that Lint (a static checker for C which does
not even have to be run before a hasty hacker goes for the
compiler and generates an incorrect executable).

I was just about to leave the room when a workmate of one of
the participants in that thread has sent an email to that
list saying that his C++ compiler did not give him an error
when he had the assignment operator in a condition. His
company does actually cater for the Ada market, but is more
involved with C++ despite being "a leading supplier" for
"real-time systems" including aerospace.

For the thread I was hoping to mention a story I thought I
heard on Team Ada, but I could not find it. Could any of you
provide me with a real life reference to mistyping C's or
C++'s == wasting time or causing more serious
trouble? Thanks.

Also, since we may have to face the inevitablity of Ada
source bases being ported to C/C++ it may be worth writing
IF rvalue = lvalue lest the port is altered manually
later. Java would be fine because if(lvalue=rvalue) is
illegal in Java but it is relatively trivial to port from
Java to C/C++ so if you only fear your code will be ported
to Java do not be so sure ... if your company abandons Java
it might transfer Java projects to C/C++.

---------- Forwarded messages from today follow ----------
Date: Tue, 19 Nov 2002 10:28:16 -0000,
from a workmate (Mister A) of a contributor (Mister B) to an
earlier discussion working for a company which sells Ada, C,
C++, and Java tools for realtime systems, concerning "if and
maybe if" ...

"Hi,

I just had a bug where I'd got a single = where I should have had ==.  I
thought that as my warning level was 4 and I have warnings as errors (MSVC[Microsoft Visual C++]),
that it would have been picked up.  But no, the only thing we can think of
is that for classes which expose operator=, the compiler doesn't perform
this check.  For example:

void f()
{
        CString s;
        if ( s = "Fred" ) {} // no warning

        int n;
        if ( n = 1 ) {} // warning
}

Anyone seen this before?  I'm in the camp that prefers the above style, and
this is a bit of a blow to the main argument against lack of integrity.
Rats."

---------------------------------------------

Date: Tue, 19 Nov 2002 11:21:20 -0000
from Mister C concerning "if and maybe if" ...

"[..Quoting Mr A:]
> Hi,
>
> I just had a bug where I'd got a single = where I should have had ==.  I
> thought that as my warning level was 4 and I have warnings as errors (MSVC),
> that it would have been picked up.  But no, the only thing we can think of
> is that for classes which expose operator=, the compiler doesn't perform
> this check.  For example:
>
> void f()
> {
> CString s;
> if ( s = "Fred" ) {} // no warning
>
> int n;
> if ( n = 1 ) {} // warning
> }
>
> Anyone seen this before?  I'm in the camp that prefers the above style, and
> this is a bit of a blow to the main argument against lack of integrity.
> Rats.

    The problem isn't that you have an assignment operator, but that CString
has an implicit user defined conversion to const char*. Without this
conversion you'd get an error, so it's not that much of a problem since you
would normally be avoiding such conversions."

---------------------------------------------


Date: Tue, 19 Nov 2002 12:09:12 -0000
Mr A...
"> Hiya,
>
> >     if ( n = 1 ) {} // warning
>
> Um, what you have there is mix up. Remember, for comparison, you need
> ==. For an assignment to n, you have n = 1.

Yes, that's what I was wanting the compiler to warn me
about, and it did, only not in the case of a CString."

---------- Forwarded messages from the past month follow ------
---------------------- (not the entire thread though) --------

In an off-list email Mr D sent to Mr E:

"I had a quick look at [..Mr D's] Embedded C Style
Guide. Some
feedback

p14. style... if(TRUE == stop)
I would advise not testing against "true". The problem is hat while
there is only one false value there are loads of"true" values (any
non-zero of course).

Also on a personal note I think reversing the test like this is not a
good idea. If you know about the possibility of using = instead of ==
then why not just take an extra moment to ensure you've used == rather
than taking an extra moment to reverse the operands? Makes the code
header to read (IMHO). I think you're better off writing clean easy to
read code and catching errors like =/== transposition via lint.

[..]"

---------------------------------------------


On the list Mr E broadcast concerning "Good C style and C
programming techniques"
"[..] [..Mr D] writes
[..]

>Also on a personal note I think reversing the test like this is not a
>good idea. If you know about the possibility of using = instead of ==
>then why not just take an extra moment to ensure you've used == rather
>than taking an extra moment to reverse the operands? Makes the code
>header to read (IMHO). I think you're better off writing clean easy to
>read code and catching errors like =/== transposition via lint.


I think I might agree with you other that the fact I have an
up hill struggle to get people to use Lint!


We all know the =/== problem [..]"

---------------------------------------------

Colin Paul Gloster emailed at Mon 04 Nov 2002 - 10:40:52
GMT:

"[.. Mr E] said:


"[..] If you know about the possibility of using = instead
of == then why not just take an extra moment to ensure
you've used == rather than taking an extra moment to reverse
the operands?"


Because 6=x can not be compiled.


"Makes the code header [easier] to read (IMHO)."


6==x and x==6 do not really require different mindsets to be
understood with ease, do they?


"I think you're better off writing clean easy to read code
and catching errors like =/== transposition via lint. [..]"


I disagree. Sure, use lint but why wait for lint to catch a
trivial statically detectable problem which can be caught by
the compiler purely on account of a programming style?


On Sat, 26 Oct 2002, [.. Mr D] responded to [.. Mr E] with:


"I think I might agree with you other that the fact I have
an up hill struggle to get people to use Lint!


[..]""

---------------------------------------------

Mr E at Mon 04 Nov 2002 - 11:44:05 GMT:

"> [..Mr E]
> said:
>
> "[..] If you know about the possibility of using = instead
> of == then why not just take an extra moment to ensure
> you've used == rather than taking an extra moment to reverse
> the operands?"
>
> Because 6=x can not be compiled.


Yes I know.

> "Makes the code header [easier] to read (IMHO)."
>
> 6==x and x==6 do not really require different mindsets to  be
> understood with ease, do they?


Depends on the mind/s in question I guess. Personally I find 6==x really
quite bizarre. It's not a huge point and I'd certainly worry about
others code issues a lot more. But I definitely prefer x==6



I don't think you should "bend" the language unnecessarily. You should
express what you want in as "natural" a fashion as you can. You don't
say/think "6 equals x" do you. You say/think "x equals 6". At least, I
do. I know you're not programming in English, but the correspondence is
valuable and the lack of surprise too. Law of Least Astonishment, etc.
Also, as I say, If you're sufficiently aware of the problem  then why not
just do the right thing in the first place?



> "I think you're better off writing clean easy to read code
> and catching errors like =/== transposition via lint. [..]"
>
> I disagree.


That's allowed ;-)


> Sure, use lint but why wait for lint to catch a
> trivial statically detectable problem which can be caught  by
> the compiler purely on account of a programming style?


Because style is not solely for the purpose of catching errors. Catching
errors in much more the domain of the language and its grammar. Eg
static typing vs dynamic typing. Style is about having a clear intention
and expressing that intention clearly.


Cheers"

---------------------------------------------

Colin Paul Gloster at Mon 04 Nov 2002 - 12:59:20 GMT:

"On Mon, 4 Nov 2002, [.. Mr E] wrote:
"[..] Also, as I say, If you're sufficiently aware of the
problem then why not just do the right thing in the first
place?


[..]"


Well, we have two options here which are right :)
x==6 might later be incorrectly changed to x=6, but I would

be more concerned about someone weaker following the
convention of having the literal on the right and writing
y=2 instead of y==2."

---------------------------------------------

Mr F at Mon 04 Nov 2002 - 11:42:30 GMT:

">6==x and x==6 do not really require different mindsets
>to be understood with ease, do they?


To me, it isn't idiomatic. Every time I see something like 6==x it distracts
me - I see the construct, not the meaning. I just can't get used to it."

---------------------------------------------

Mr G at Mon 04 Nov 2002 - 11:44:05 GMT:

"> "[..] If you know about the possibility of using = instead
> of == then why not just take an extra moment to ensure
> you've used == rather than taking an extra moment to reverse
> the operands?"
>
> Because 6=x can not be compiled.
>
> "Makes the code header [easier] to read (IMHO)."
>
> 6==x and x==6 do not really require different mindsets to be
> understood with ease, do they?


I personally find 6==x harder to read and x==6. Moreover, this style doesn't work
when you write x==y or y==x. There, you just have to make sure you've written ==
and not =. So you have to make sure you use the right operand anyway."


---------------------------------------------


Mr H at Mon 04 Nov 2002 - 13:39:03 GMT:

"> > "[..] If you know about the possibility of using = instead
> > of == then why not just take an extra moment to ensure
> > you've used == rather than taking an extra moment to reverse
> > the operands?"
> >
> > Because 6=x can not be compiled.
> >
> > "Makes the code header [easier] to read (IMHO)."
> >
> > 6==x and x==6 do not really require different mindsets to be
> > understood with ease, do they?
>
> I personally find 6==x harder to read and x==6.
> Moreover, this style doesn't work when you write x==y or y==x.
> There, you just have to make sure you've written ==
> and not =. So you have to make sure you use the right operand anyway.


I tend to agree that in more cases we have at least one of the == arguments
being an rvalue (otherwise, this idiom does not buy much anyway),
but this means we have to get used to expressions like
        (a + b)/a*c == x and f(a, b + c) == x


Personally, I prefer gcc attitude, that warns for each and every = expression
that is put in a boolean context. This warning is shut off
by placing extra () around the expression. This way the programmer
puts the extra work where it is required - at the exceptional cases!


Enjoy"

---------------------------------------------

At Mon 04 Nov 2002 - 13:54:17 GMT Colin Paul Gloster
emailed:

"On Mon, 4 Nov 2002, [.. Mr G] wrote:
"> "[..] If you know about the possibility of using =
instead
> of == then why not just take an extra moment to ensure
> you've used == rather than taking an extra moment to reverse
> the operands?"
>
> Because 6=x can not be compiled.
>
> "Makes the code header [easier] to read (IMHO)."
>
> 6==x and x==6 do not really require different mindsets to  be
> understood with ease, do they?


I personally find 6==x harder to read and x==6. Moreover,
this style doesn't work
when you write x==y or y==x. There, you just have to make
sure you've written ==
and not =." So you have to make sure you use the right
operand anyway."


Even with 6==x the operator has to be written properly. With
x==6 there is greater risk of the operator being mistyped
and not noticed for a long time. I wanted to include a
link to a tale of a C/C++ project which took two days
in debugging trying to track down a bug which was
due to mistyping == as = but I have not found it
again.


Since x and y are not literals, they are not covered by the
style. I would not go so far as to say that they style does
not work when there are no literals."

---------------------------------------------

At Mon 04 Nov 2002 - 13:38:05 GMT C++ expert Mr I who has
lectured to Ada users said:

"[.. Mr F] writes
>
>>6==x and x==6 do not really require different mindsets
>>to be understood with ease, do they?
>
>To me, it isn't idiomatic. Every time I see something like  6==x it distracts
>me - I see the construct, not the meaning. I just can't get used to it.


Agreed. And the argument "it's what you're used to" just doesn't wash:
I've seen this style for over a decade and it still looks odd. I've
always felt it to be nothing more than an affectation designed to
distract the programmer under the guise of being a "good programming
practice".


Programmers that genuinely care about avoiding this kind of  mistake
should focus on practices that more generally avoid it, eg const
correctness and compiler warning levels, instead of focusing on bitty
practices that give the illusion of good practice."

---------------------------------------------

At Mon 04 Nov 2002 - 14:36:00 GMT Mr B who works for the
same company as Mr A who started today's if thread on
the aforementioned mainly C++ list said:

"I agree. I started doing this a while ago but don't like the way it looks. I
have to make a concious effort to put the literal on the left and if I can
make that effort then I could instead make the effort to ensure I have ==
rather than =. As such I stopped doing it quite recently.


[..Quoting Mr I:]

> Agreed. And the argument "it's what you're used to" just doesn't wash:
> I've seen this style for over a decade and it still looks odd. I've
> always felt it to be nothing more than an affectation designed to
> distract the programmer under the guise of being a "good programming
> practice"."

------------------------------------

At Mon 04 Nov 2002 - 14:34:13 GMT Mr J said:

"> -----Original Message-----
> From: Colin Paul Gloster [..]


> Even with 6==x the operator has to be written properly. With
> x==6 there is greater risk of the operator being mistyped
> and not noticed for a long time. I wanted to include a
> link to a tale of a C/C++ project which took two days
> in debugging trying to track down a bug which was
> due to mistyping == as = but I have not found it
> again.


So, I hope they drew the conclusion that they could save future
two-day-debugging-for-nothing sessions by using all the code checking tools
at their disposal (and putting those tools at their disposal of course).


The thing is, C++ inherits failings of C such as assignments having a value
and integers used as boolean expressions and as a consequence, you need
tools to warn you whenever you might fall foul of these.
The fact that those tools can go on to catch other less fundamental problems
is a bonus.



Regards,"

----------------------

Mr K at Mon 04 Nov 2002 - 16:13:08 GMT:

"Looking at the whole question, it's a bit of a shame that both C and C++
fail to mandate an alternative token for '==' (for example, 'eq').

[..]"

------------------------

Mr L at Tue 05 Nov 2002 - 14:29:47 GMT:

"I tried using 6==x rather than x==6 for comparisons a few years ago, but I
gave up on the technique for a number of reasons. One reason that has
already been mentioned is that it doesn't map to my natural  language
(English) very well. "x is 6" is much better than "6 is the value x has".


A couple of comments have been made about the use of lint to pick up
accidental use of "x=6" in conditional statements. I don't bother - I just
turn the appropriate warning on in the compiler. OK, the code still
compiles (it is only a warning, after all) but as I have a policy of "all
code shall compile with no warnings" even one warning shouts out nice and
loud without needing a separate Lint pass. Indeed I now have so many
warnings turned on that if it gets through the compiler it almost always
gets a clean bill of health from Lint too.


Interestingly, I do lay out some other conditional statements in a way
some of my colleagues have found useful, for example:


   if (6 < x && x < 10) // x is between 6 and 10


   if (x < -5 || 5 < x) // x is outside the range +/-5


i.e. I always use the less-than operator whenever I have multiple
conditions (and usually for single conditions too) and I arrange the
elements in increasing numerical order. This has the added advantage that
the variable appears "inside" or "outside" the range as appropriate. What
do others think of these ideas?


Cheers,"

-------------------------

Mr F at Tue 05 Nov 2002 - 16:48:58 GMT:

">Interestingly, I do lay out some other conditional statements in a way
>some of my colleagues have found useful, for example:
> if (6 < x && x < 10) // x is between 6 and 10
> if (x < -5 || 5 < x) // x is outside the range 5


That is a good map for mathematical notation, so is
acceptable IMO. Once
you've learned the idiom, it's easy to use, which 6==x is
not, IMO."

------ Forwarded two messages from another new thread follow ----------

In another thread started today, at Tue, 19 Nov 2002
12:59:22 -0000 Mr J wrote concerning "If
only..."...

"Why, why, why does C++ have to allow if/while etc.( anything other than bool
)?
Why, why, why does C++ have to allow implicit conversions with bool?
Does ten years of legacy code *have* to leave us with a broken language
forever?

Just a thought. I realise that no one cares a damn but I thought I'd just
say it anyway.:-)"

------------------------------

Mr G at Tue, 19 Nov 2002 13:52:48 +0000 concerning "If
only..."...
"[Quoting Mr J:]
> Why, why, why does C++ have to allow if/while etc.( anything other than bool
)?
> Why, why, why does C++ have to allow implicit conversions with bool?
> Does ten years of legacy code *have* to leave us with a broken language
forever?

That wouldn't solve the problem:

bool a = false, b = true;
...
if (a = b) {...}

Oops, the programmer meant to write if (a == b).
But the (hypothetical strict-bool) compiler still hasn't caught it."