Is this C program doing what it is supposed to do ?

L

luser- -droog

In message <[email protected]>, Eric Sosman


On 2/6/2011 12:39 PM, Chris H wrote:
[...]
It isn't but the original line was
flag = foo == bar;
No, the original line was
while( (ch==getchar())!= EOF){
Please don't fabricate "facts" in support of your argument,
not even if you have a good one. The ends do not justify
the dishonest means.
   Chris, I apologize for writing this.  A simple ambiguity or
at worst a mistake is no reason for me to hurl injurious words
like "dishonest" around, and I should not have done so.  Again,
I am sorry, and I will try behave more civilly henceforth.

Apology accepted. Email is not a good way to have a conversation and
things tend to get miss understood.

However, as you say "a simple ambiguity"  and that is my point. When
coding you need no ambiguities or  implied things. It should all be
explicit.

Like machine code? Is there no room for notational convenience,
or higher-level systems? Or hybrids?
 
A

Anders Wegge Keller

If you dont see then you havent been C programmer for any note for
any appreciable time and you fail to see how reduced code == easier
to read and less errors.

If you cannot explain *WHY* the cramped style is safer, then you lose
the argument. Repeating the fallacy that fewer characters means fewer
errors is not an explanation.
f=(a==b)

is a well known C paradigm/stylism that is small, compact, pretty,
reliable and easy.

The original code was "a = b == c;", so I will pretend that you
didn't move the goalpost on purpose.

My experience tells me otherwise. The problem is not usage in a
simple case like this, where it's just a nuisance, when I hav to guess
the intention. But the coding style creeps into more and more complex
structures, where you end up with code that is more clever than the
programmer or the compiler[1].
The bloated nonsense above is more likely to provoke a programmer to
think there is more to it than there is.

Whereas I have to guess if "a = b == c" is intended or not, I have no
doubt what was intended with the explicit if. You may have the
privilege of never touching code you haven't written yourself. I
don't, which have made me a bitter and grumpy old man.
If you dont think

if(f=(a==b))
{
/* */
}
is succinct and easy then you shouldnt be programming in C IMO and
most certainly not teaching others.

You are moving the goalposts again. This time you are inventing a
completely different pattern. I have never stated an opinion about
this, but if you feel you have to argue against a strawman, Ã'll take
that as an apology.

I don't teach C, I just fix the mistakes of a decade worth of
"clever" people who confuse terseness with clarity.

1. SCO OpenServer Development System.
 
C

Chris H

Richard said:
If you dont see then you havent been C programmer for any note for any
appreciable time and you fail to see how reduced code == easier to read
and less errors.

This is CRAP the studies show otherwise.
f=(a==b)

is a well known C paradigm/stylism that is small, compact, pretty,
reliable and easy.

But the line was

f=a==b

The bloated nonsense above is more likely to provoke a programmer to
think there is more to it than there is.

If you dont think

if(f=(a==b))
{
/* */
}

is succinct and easy then you shouldnt be programming in C IMO and most
certainly not teaching others.

Now you see the problems we face.
 
H

Hans Vlems

Hans Vlems said:
[snip]
Well, if only C had built-in support for booleans ;-)
Were you unaware that it does?
But even in pure C90, which doesn't have _Bool/bool, the lack of
*direct* support for a boolean type is largely irrelevant.  Several
built-in operators ("==", "<", "!", etc.) yield int results that are
either 0 or 1, representing false or true results.
[snip]
<g>
I'm aware of C90's boole type and the way an int is easily used as a
substitute.
When posting a followup, it's best to quote just enough of the
parent article so that your followup makes sense.  In particular,
it's best not to quote signatures unless you're commenting on them.
Read my earlier posts; look for the [snip] entries :)
Text is possibly the worst way to clarify an issue.

Text is all we've got here.  If you're not interested in clarifying
what you wrote before, I guess there's nothing else to say.

I find it frustrating when someone disagrees with something I've
written and doesn't clearly explain why, or respond to questions
about it.  I *like* having my ideas challenged.  It's always possible
that I'm wrong, and that someone else has a better idea than I do.
But if you aren't willing to enage in discussion, then neither of
us will learn anything.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"- Tekst uit oorspronkelijk bericht niet weergeven -

- Tekst uit oorspronkelijk bericht weergeven -

Keith, this usenet group is more about language syntax rather than its
perceived semantic beauty ;-)
And I felt that my point was too much of the latter.
My point was that in a language that supports the type boolean, it
usually has two states TRUE or FALSE (whatever way it gets
implemented).
So a construct like b:=<boolean expression> is very much in line with
the sematics of such a language.
In C, any non-zero value translates to TRUE. Convenient, the standard
libraries rely on it.
At the same time it makes e hesitate to write if (b==1) in C because
it is not the same as if (b).
The workaround is if (b!=0) but that is (to me) less pleasing to the
eye and, IMVHO, confuses the issue of a boolean expression.

An expression like:
if (c==684)
b=1;
else
b=0;
which came up in onother track of this post, obviously has its
supporters here.
In Algol or Pascal,
IF (C=684) THEN B:=TRUE ELSE B:=FALSE;
is fairly ugly,
B:=C=684;
is "better".
Perhaps the fact that the choice of assignment operator in Algol and
Pascal makes a difference.
Hans
 
H

Hans Vlems

Ok.

I agree that the parentheses make it clearer; I also prefer
    flag = (foo == bar);
to
    flag = foo == bar;
though not as strongly as you do.

I've been asking for some time now for you to clarify this point.
We could have saved considerable time if you had done so sooner.

I prefer the second form, provided flag is a boolean that is either
true or false.
The way it works in C is that the second form is actuall a test of
"compare this value with zero".
Which is, while a valid boolean expression, not the same as a boolean.
Hans
 
B

Ben Bacarisse

Anders Wegge Keller said:
Would you at the same time explain why you think this is a safe and
beutifull piece of code?

I can't say it's beautiful because I don't think it is and I never
claimed it was. The code is safe in as much as it is correct. It is
also unsafe in that all code is prone to errors.

The main point was to bring together into one place the condition that
set at_beginning. In the original code, it was set conditionally in two
places. Simpler logic makes for safer programs.

I don't understand the fear people seem to have about typos. I don't
remember any hard to find bugs that were down to operator confusions or
miss-bracketing of expressions. Unit tests usually pick them up. All
the hard bugs and maintenance problems that have stuck in my mind come
from overly complex code or logical errors[1]. I'll always opt to keep
the logic as clear and simple as possible.

The suggestion I made was not supposed to end up in an argument about
brackets (I would not have commented further if the only remark had been
in favour of bracketing the conditional) but was meant to highlight
keeping the logic simple. Of course, it always looks trivial in a
simple program like this, but when programs get bigger I'd rather read
one with clear logic but which requires me to know C's precedence rules
than one with tortured logic and few more brackets.

[1] There's an even bigger maintenance problem with design or
"architecture" errors but that's another matter altogether.
 
C

Chris H

Richard said:
Not in my considerable experience with decent programmers.

I am not sure you would recognise one. You have an ego in the way.
I can believe
it is the case when studying nOObs. I dont program to the least skilled
level.

:) Nuff said.

I have had to debug code from people like you.

I would, as would any programmer I worked with, bracket it. Never leave
it to people understanding precedence.

So you agree with me then
 
B

Ben Bacarisse

Anders Wegge Keller said:
Not really. I just see a stated opinion, which is what I'm curious to
hear the reasoning behind.

Ultimately that is all we have. I doubt either of us an sound scientific
evidence for our positions but I have also said more in another post.
I hope that it will explain my view even if it does not convince you.
I've been writing C for a living since 1998, so I know about the
syntax. I just fail to see how it is in any way safer, clearer or in
any other better than this:

if (ch == '\n') {
at_beginning = 1;
} else {
at_beginning = 0;
}

That was not the alternative I was commenting on. However, I still that
this is overly long winded though it does not complicate the logic much.
Showing off doesn't score high with me. And that is the only reason
for coding in that cramped style.

I am not happy that anyone thinks I was showing off but there is nothing
that I can do about that. Maybe we should have a thread about overly
clever code constructs so that we can see what is considered tricksy and
what is considered simple code.
at_beginning = ch == '\n';
at_beginning = ch = '\n';

Both of the lines are equally plausible, when seen by themselves.

Absolutely not. Had the variable been called x, yes, but I also
strongly urged the use of a "biased" name. Once I've seen "at_beginning
= " I expect a conditional and an alarm bell ring if I don't see on. To
me, the above look shockingly different.
 
B

Ben Bacarisse

Anders Wegge Keller said:
The original code was "a = b == c;", so I will pretend that you
didn't move the goalpost on purpose.

You've moved them! The names of the variables, the constant involved
and the context all matter.

In the original, miss-reading (or typing) = for == would leave the
reader wondering why at_beginning was always being set, unconditionally,
in a loop, to \n'.

Whereas I have to guess if "a = b == c" is intended or not, I have no
doubt what was intended with the explicit if.

To my mind it is clear what is intended. If you clip the context and
change the variables and the constant involved, sure, you can make it
confusing. In

if (b == c) {
a = 1;
} else {
a = 0;
}

I have to guess that 0 and 1 were intended and that the order is
correct. I can't tell from the variable names and condition alone.

<snip>
 
A

Anders Wegge Keller

I can't say it's beautiful because I don't think it is and I never
claimed it was. The code is safe in as much as it is correct. It
is also unsafe in that all code is prone to errors.

If you don't particular like it, why defend it in the first place?
The main point was to bring together into one place the condition
that set at_beginning. In the original code, it was set
conditionally in two places. Simpler logic makes for safer
programs.

There is no such thing as simple logic in the real world. The pattern
may start out being benign and somewhat readable, but when several
iterations of changed requirements hyave transformed it into a mess of:

some_condition = (input == 0x42 ||
moon_phase = M_WAXING && input == 042) &&
a_hideously_long_name_caused_by_a_fad_in_2003 != flabbergast;

Then you won't spot the typo. Notice how the guy who added the last
clause in 2003 despaired of understanding it, and wrapped the whole
mess in (), in order to feel better about it.

Except for the names, this is actual code created by hybridizing the
patterns "a = b == c" and "Add yet another boundary condition". I have
seen my share of crappy code, as have anyone working os customer
customized projects, and I know where the evil starts.
I don't understand the fear people seem to have about typos. I
don't remember any hard to find bugs that were down to operator
confusions or miss-bracketing of expressions.

Did you spot it before I mentioned it?

[snip]
 
A

Anders Wegge Keller

You've moved them! The names of the variables, the constant involved
and the context all matter.

Actually, Richard started by boiling it down to single letter names.
In the original, miss-reading (or typing) = for == would leave the
reader wondering why at_beginning was always being set,
unconditionally, in a loop, to \n'.

I'm not particularly interested in this specific situation. I'm
advocating against the pattern itself, as it leads to horrible
code. Even inside brackets, it becomes an eysore in some cases:

if ( ( i = sscanf( &buf[0], Format,
&tmpstr[0][0], &tmpstr[1][0], &tmpstr[2][0]))
== NUM_Fields ) {

If you pick apart the bits, you will find "i = (sscanf() ==
NUM_Fields)" inside it. It even have the set of brackets that some
have deemed adequate for making stuff clear. I seriously hope that you
will agree that this is not an example of a piece of code that is made
clearer and more readable by a = b == c.
To my mind it is clear what is intended. If you clip the context and
change the variables and the constant involved, sure, you can make it
confusing. In

Patterns will be used, even where they are not appropriate.
if (b == c) {
a = 1;
} else {
a = 0;
}

I have to guess that 0 and 1 were intended and that the order is
correct. I can't tell from the variable names and condition alone.

The world hardly ever provides situations as simple as this textbook
example.
 
B

Ben Bacarisse

Anders Wegge Keller said:
If you don't particular like it, why defend it in the first place?

Eh? I prefer it and I said why.
There is no such thing as simple logic in the real world.

No and I did not say that. I said "simpler" and some logic is simpler
than others. The OP had logic that was, to my mind, more complex than
it need be.
The pattern
may start out being benign and somewhat readable, but when several
iterations of changed requirements hyave transformed it into a mess of:

some_condition = (input == 0x42 ||
moon_phase = M_WAXING && input == 042) &&
a_hideously_long_name_caused_by_a_fad_in_2003 != flabbergast;

Then you won't spot the typo.

Why not, it seems obvious to me? Why would the tests not pick this up
immediately? Why is the typo "hidden" in that code and not in something
like this?

if ((input == 0x42 ||
moon_phase == M_WAXING && input == 042) &&
a_hideously_long_name_caused_by_a_fad_in_2003 != flabbergast) {
some_condition = 0;
} else {
some_condition = 1;
}

Anyway, this is not the point! I don't mind if you insist on writing a
if to set a logical variable (though I see it as no safer to do so -- it
just introduces more opportunities for errors). The original code set
the variable in two places (conditionally) and it is that trend that I
was warning against. If modifications continue to add further places
where it is set, the logic will deteriorate even further.

If the program's evolution requires that the condition gets more
complex, so be it. There is nothing one can do about that other than,
at some point, moving the condition into a separately documented function.
Notice how the guy who added the last
clause in 2003 despaired of understanding it, and wrapped the whole
mess in (), in order to feel better about it.

No, I see that they needed the brackets to get the right meaning or, if
they did it to "feel better about it" rather than needing it they have
introduced a bug. Exactly the same applies to both versions -- the
extra brackets are either needed or they are a bug. Obviously I can't
say which without know the purpose of the code.
Except for the names, this is actual code created by hybridizing the
patterns "a = b == c" and "Add yet another boundary condition". I have
seen my share of crappy code, as have anyone working os customer
customized projects, and I know where the evil starts.


Did you spot it before I mentioned it?

Of course I did.
 
K

Keith Thompson

Anders Wegge Keller said:
You've moved them! The names of the variables, the constant involved
and the context all matter.

Actually, Richard started by boiling it down to single letter names.
In the original, miss-reading (or typing) = for == would leave the
reader wondering why at_beginning was always being set,
unconditionally, in a loop, to \n'.

I'm not particularly interested in this specific situation. I'm
advocating against the pattern itself, as it leads to horrible
code. Even inside brackets, it becomes an eysore in some cases:

if ( ( i = sscanf( &buf[0], Format,
&tmpstr[0][0], &tmpstr[1][0], &tmpstr[2][0]))
== NUM_Fields ) {
[snip]

That's *very* different from the original example.

The original example was something like:

at_beginning = ch == '\n';

or, with parentheses (which I agree are helpful):

at_beginning = (ch == '\n');

This expression has *no* side effects other than the top-level
assignment.

You're extrapolating from this to an expression used as an if()
condition with a subexpression that has the side effect of assigning
a value to an object.

Speaking only for myself, I probably wouldn't write your more complex
example; I'd probably write the assignment as a separate statement,
and I'd choose a name other than "i". But I have to be prepared
to read and understand that kind of expression when reading C code
written by others.

But I find

at_beginning = (ch == '\n');

perfectly clear and less error-prone than the if/else alternative.

(On the other hand, it does have a different meaning than

if (ch == '\n') {
at_beginning = 1;
}

which leaves at_beginning alone when ch != '\n'.)
 
K

Keith Thompson

Hans, you appear to have ignored this advice.

[...]
Keith, this usenet group is more about language syntax rather than its
perceived semantic beauty ;-)
And I felt that my point was too much of the latter.

This particular discussion is mostly about semantic beauty, and there's
nothing wrong with that. It's a big part of good programmng in C.
My point was that in a language that supports the type boolean, it
usually has two states TRUE or FALSE (whatever way it gets
implemented).
So a construct like b:=<boolean expression> is very much in line with
the sematics of such a language.

Of course.
In C, any non-zero value translates to TRUE. Convenient, the standard
libraries rely on it.
At the same time it makes e hesitate to write if (b==1) in C because
it is not the same as if (b).
The workaround is if (b!=0) but that is (to me) less pleasing to the
eye and, IMVHO, confuses the issue of a boolean expression.

So write "if (b)" -- and give "b" a name that clearly indicates that it
represents a condition.
An expression like:
if (c==684)
b=1;
else
b=0;
which came up in onother track of this post, obviously has its
supporters here.
In Algol or Pascal,
IF (C=684) THEN B:=TRUE ELSE B:=FALSE;
is fairly ugly,
B:=C=684;
is "better".

Yes, and I find the C equivalent better for exacly the same reasons.
Perhaps the fact that the choice of assignment operator in Algol and
Pascal makes a difference.

My point is that we needn't be entirely limited by the semantics of the
language we're using. C90 doesn't have a boolean type. C99 does, but
the equality and relational operators still yield results of type int,
and conditions are still defined in terms of comparison to zero.

Nevertheless, we can write clear code that treats boolean expressions as
boolean expressions. We don't have to get lost in an analysis of how
each expression is evaluated in whatever context it appears in. With
carefully chosen idioms, we can write code that expresses its intent as
clearly as possible, without adding unnecessary verbosity just because
there's no explicit boolean type, or just because we don't happen to be
using it.

We can write:

at_beginning = (ch == '\n');
...
if (at_beginning) {
...
}

and the code works *exactly* the same way as it would if "=="
yielded a bool result and if() took a bool condition.

The extra verbosity of

if (ch == '\n') {
at_beginning = 1;
}
else {
at_beginning = 0;
}

gains us exactly *nothing*.
 
K

Keith Thompson

Anders Wegge Keller said:
If you don't particular like it, why defend it in the first place?


There is no such thing as simple logic in the real world.

Yes, there is.
The pattern
may start out being benign and somewhat readable, but when several
iterations of changed requirements hyave transformed it into a mess of:

some_condition = (input == 0x42 ||
moon_phase = M_WAXING && input == 042) &&
a_hideously_long_name_caused_by_a_fad_in_2003 != flabbergast;

Then you won't spot the typo. Notice how the guy who added the last
clause in 2003 despaired of understanding it, and wrapped the whole
mess in (), in order to feel better about it.

Ok, so something that started out as a perfectly reasonable assignment
statement:
some_condition = (foo == bar);
gradually mutated into a confusing mess. That's no reason not to write
the perfectly reasonable assignment in the first place.

Are you suggesting that
if (foo == bar) {
some_condition = 1;
}
else {
some_condition = 0;
}
is immune to such problems? Isn't it more likely that a maintenance
programmer would try to make the same change to both branches of
the if/else, and likely get one of them wrong?
Except for the names, this is actual code created by hybridizing the
patterns "a = b == c" and "Add yet another boundary condition". I have
seen my share of crappy code, as have anyone working os customer
customized projects, and I know where the evil starts.

The evil start when you take existing clean code and make it overly
complex. The solution isn't to avoid writing clean code in the first
place. The solution is to be more careful during maintenance.

[...]

Let's suppose that, apart from the typo (042 for 0x42), the above
expression accurately reflects the intended semantics. How would
you write it more clearly? Personally, I'd add at least one set of
parentheses and align the subexpressions to reflect the semantic
grouping. I'd also pick more meaningful names. But I'd probably
keep the pattern of assigning the result condition to a variable
with a meaningful name.

Would you replace all the "&&" and "||" operators with a nest of
if/else statements?
 
B

Ben Bacarisse

Anders Wegge Keller said:
Actually, Richard started by boiling it down to single letter names.

OK, but you did not need to keep them! They do matter.
In the original, miss-reading (or typing) = for == would leave the
reader wondering why at_beginning was always being set,
unconditionally, in a loop, to \n'.

I'm not particularly interested in this specific situation. I'm
advocating against the pattern itself, as it leads to horrible
code. Even inside brackets, it becomes an eysore in some cases:

if ( ( i = sscanf( &buf[0], Format,
&tmpstr[0][0], &tmpstr[1][0], &tmpstr[2][0]))
== NUM_Fields ) {

If you pick apart the bits, you will find "i = (sscanf() ==
NUM_Fields)" inside it.

Eh? All I can see is what is written and it's not of that form. Its
shape is (i = sscanf(...)) == CONST and the brackets are required
(unless they are a big of course).

Had i = (sscanf() == CONST) been the intended shape (maybe written
without the parentheses) then I'd be very wary of it because 'i' is such
a bad name of a logical variable -- it should have been a "biased" name
like 'parse_ok' or 'all_inputs_seen' or some such.
It even have the set of brackets that some
have deemed adequate for making stuff clear. I seriously hope that you
will agree that this is not an example of a piece of code that is made
clearer and more readable by a = b == c.

Surely it would simply be wrong if it were re-written using the a = b ==
c pattern (including a = (b == c))? In this case clarity does not come
into it.

Yes -- I agree that as conditions get more complicated, brackets help
more and more -- but in this specific case it looks correct and
minimally bracketed. I'd prefer a better name than 'i' and I am not a
fan of the &E[0] pattern so I'd probably have written:

if ((n_inputs = scanf(buf, Format,
tmpstr[0], tmpstr[1], tmpstr[2]))
== NUM_Fields) {

but none of that has much to do with what we've been discussing.

<snip>
 
C

Chris H

Keith Thompson <kst- said:
Ok, so something that started out as a perfectly reasonable assignment
statement:
some_condition = (foo == bar);


No it started as

some-condtion= foo==bar;
 
A

Anders Wegge Keller

Yes, there is.

If that holds true for you, then you are one lucky guy :)

With the risk of making this sound like a rant, My world consists of
an event driven control system, distributed over anything from 15 to
45 processes, 3 to 5 interface cards with their own CPU, talking to a
bunch of distributed nodes, with yet another level of code. That mess
controls various sorting machines that generate events by means of
upwards of 50 operators doing stuff in a random order.

Ok, so something that started out as a perfectly reasonable assignment
statement:
some_condition = (foo == bar);
gradually mutated into a confusing mess. That's no reason not to write
the perfectly reasonable assignment in the first place.

In other contexts, this would be called the gateway drug. Putting yet
another conditional on top of the pile works fine in most cases, until
someone suddenly screw up, I get a phonecall at 3 am, and have to
figure out that piece of code with a plant manager screaming on the
phone telling me just how much overtime he have to pay.
Are you suggesting that
if (foo == bar) {
some_condition = 1;
}
else {
some_condition = 0;
}
is immune to such problems? Isn't it more likely that a maintenance
programmer would try to make the same change to both branches of the
if/else, and likely get one of them wrong?

If the same code goes into both branches, then someone is doing a
very bad job. I'm talking about the conditions before that.
The evil start when you take existing clean code and make it overly
complex. The solution isn't to avoid writing clean code in the
first place. The solution is to be more careful during maintenance.

I know. Yet, I do not have the privilege of working in an
environment, where that is practiced at all times. Normally, the
combination of eager project manager, customers with an urgent need
for some change to the buisness logic, and a nearby deadline combines
to sloppy code. Again, if that is a fact you have not had to live
with, I envy you.
[...]

Let's suppose that, apart from the typo (042 for 0x42),

Actually, the typo was here: moon_phase = M_WAXING
the above expression accurately reflects the intended semantics.
How would you write it more clearly? Personally, I'd add at least
one set of parentheses and align the subexpressions to reflect the
semantic grouping. I'd also pick more meaningful names. But I'd
probably keep the pattern of assigning the result condition to a
variable with a meaningful name.

I had to change the names to protect the guilty parties. I tried to
convey the general spirit of them, though.

In this case, the whole mess was refactored away because of changes
made outside this bit. If that hadn't been the case, I'd at least have
put the conditionals into an if statement, leading to the
assignment. In my opinion the readability of a multi-line perlish
construction (assignment - condition) is nil. So the least effort
would be to change the order, so the flow looked like (condition -
assignment)
Would you replace all the "&&" and "||" operators with a nest of
if/else statements?

In this case I would, had it been the only change needed.
 
A

Anders Wegge Keller

Keith Thompson said:
if ( ( i = sscanf( &buf[0], Format,
&tmpstr[0][0], &tmpstr[1][0], &tmpstr[2][0]))
== NUM_Fields ) {
[snip]

That's *very* different from the original example.

The pattern is the same. Written by someone, who 17 years ago was
fresh out of school, knowing that a = (b == c) would remove the need
for if.
The original example was something like:

at_beginning = ch == '\n';

or, with parentheses (which I agree are helpful):

at_beginning = (ch == '\n');

This expression has *no* side effects other than the top-level
assignment.

That is still the first step into the shady world.
You're extrapolating from this to an expression used as an if()
condition with a subexpression that has the side effect of assigning
a value to an object.

I've been mentioning all the time that my objection is to the general
*pattern*, not the particular case.
Speaking only for myself, I probably wouldn't write your more
complex example; I'd probably write the assignment as a separate
statement, and I'd choose a name other than "i". But I have to be
prepared to read and understand that kind of expression when reading
C code written by others.

You would have skipped the i entirely (or removed it later on), as it
isn't used for anything beyond this point, in the current version of
the code.
But I find

at_beginning = (ch == '\n');

perfectly clear and less error-prone than the if/else alternative.

Right up until the point where it isn't safe anymore. In that
respect, it's like being a "little bit" pregnant.
(On the other hand, it does have a different meaning than

if (ch == '\n') {
at_beginning = 1;
}

which leaves at_beginning alone when ch != '\n'.)

Depending on code flow, the 0 assigment could be placed at another
point. But you may recall that I actually listed an else in my
preferred way.
 
A

Anders Wegge Keller

Ben Bacarisse said:
Eh? I prefer it and I said why.

In this context I fail to see why this is different from you saing
it's safe and beautifull.
Why not, it seems obvious to me? Why would the tests not pick this
up immediately? Why is the typo "hidden" in that code and not in
something like this?

Becuse I do not have the possibility of exhaustive testing. I don't
even have unit tests. What I have is a simulation of the machines our
software controls, and that's it. In this case, input hardly ever was
34, meaning that this lived for a long time.

if ((input == 0x42 ||
moon_phase == M_WAXING && input == 042) &&
a_hideously_long_name_caused_by_a_fad_in_2003 != flabbergast) {
some_condition = 0;
} else {
some_condition = 1;
}
Anyway, this is not the point! I don't mind if you insist on
writing a if to set a logical variable (though I see it as no safer
to do so -- it just introduces more opportunities for errors). The
original code set the variable in two places (conditionally) and it
is that trend that I was warning against. If modifications continue
to add further places where it is set, the logic will deteriorate
even further.

We are talking about two entirely different things here. I'm dead set
against the pattern of making conditional statements, be it
assignments or other statements, without a clearly visible if () { }
[else { }] construct. If I wanted to write perl, I'd do it in that
language.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,220
Latest member
AugustinaJ

Latest Threads

Top