Did you know?

  • Thread starter Vijay Kumar R Zanvar
  • Start date
N

nrk

Vijay said:
Did you know that the following if statement is semantically
right, but could logically be wrong?

if ( i = 2 )
{
/* do something */
}

Tip:

The compiler may only produce a waring: "Possibly incorrect
assignment", but we may ignore it. To avoid such a mistake,
just reverse the two identifiers.

Did you know that only a moron (talk about fools rushing in...) would
ignore a compiler diagnostic without giving it considerable attention
and thought? Did you also know that such morons richly deserve the
demons that fly out of their nasal cavities?
if ( 2 == i )
{
/* do something */
}

If '==' is replaced by an '=', the compiler will give an error
saying "Lvalue required".

Looks cute, but is highly counter-intuitive to me. The cognitive
dissonance it induces in me is sufficient to prevent me from using it ever.

-nrk.
 
C

Chris Dollin

CBFalconer said:
We have been around this before. Clarity is in the eye of the
beholder. I consider anything that catches silly errors
beneficial. This is an error that can escape code review very
easily.

I find it hard to believe that the bad code won't fail its tests,
though.
 
K

Keith Thompson

Chris Dollin said:
I find it hard to believe that the bad code won't fail its tests,
though.

Actually, I find it quite easy to believe. For example:

int result = how_many_widgets();

if (result = 1) {
/*
* Oh good, we have exactly 1 widget, go ahead and process it.
*/
process_single_widget();
}
else {
/*
* We don't have exactly 1 widget, something has gone horribly
* wrong. It's a good thing we checked the result so we can
* detect this error.
*/
fprintf(stderr, "Horrors, we have %d widget(s)\n", result);
exit(EXIT_FAILURE);
}

If the error escapes code review, it won't show up until something
goes horribly wrong and the program calls process_single_widget()
anyway.

Personally, I think the best solution is to make sure your code is
written and reviewed by people who know the difference between "=" and
"==". (Yeah, that's glib; I'd also require programmers to pay
attention to warnings.)

Actually, the *best* solution is to hop into a time machine and tell
Dennis Ritchie to use "=" for equality and ":=" for assignment, or
something similarly distinctive. It's a pity that time machines
invoke undefined behavior (real demons, real noses).
 
M

Mike Wahler

Keith Thompson said:
Actually, I find it quite easy to believe. For example:

int result = how_many_widgets();

if (result = 1) {
/*
* Oh good, we have exactly 1 widget, go ahead and process it.
*/
process_single_widget();
}
else {
/*
* We don't have exactly 1 widget, something has gone horribly
* wrong. It's a good thing we checked the result so we can
* detect this error.
*/
fprintf(stderr, "Horrors, we have %d widget(s)\n", result);
exit(EXIT_FAILURE);
}

If the error escapes code review, it won't show up until something
goes horribly wrong and the program calls process_single_widget()
anyway.

Personally, I think the best solution is to make sure your code is
written and reviewed by people who know the difference between "=" and
"==". (Yeah, that's glib; I'd also require programmers to pay
attention to warnings.)

Actually, the *best* solution is to hop into a time machine and tell
Dennis Ritchie to use "=" for equality and ":=" for assignment, or
something similarly distinctive. It's a pity that time machines
invoke undefined behavior (real demons, real noses).

Another way (I wouldn't use it though) is:

#define eq ==

if(this eq that)
/* whatever */

-Mike
 
C

Chris Dollin

Keith said:
Actually, I find it quite easy to believe. For example:

int result = how_many_widgets();

if (result = 1) {
/*
* Oh good, we have exactly 1 widget, go ahead and process it.
*/
process_single_widget();
}
else {
/*
* We don't have exactly 1 widget, something has gone horribly
* wrong. It's a good thing we checked the result so we can
* detect this error.
*/
fprintf(stderr, "Horrors, we have %d widget(s)\n", result);
exit(EXIT_FAILURE);
}

If the error escapes code review, it won't show up until something
goes horribly wrong and the program calls process_single_widget()
anyway.

If you want to write this code, then you want to test it, so you
need a test that enforces the situation where you have 17 widgets
and makes sure the error is detected, and that test will fail.

I agree that the `exit(1)` may cause a smidgin of difficulty; there
are ways round it - such as, in this horrible situation, log the
message and process any one of the widgets.

Or of course make it work for many widgets ...
 
N

Neil Cerutti

Actually, I find it quite easy to believe. For example:

int result = how_many_widgets();

if (result = 1) {
/*
* Oh good, we have exactly 1 widget, go ahead and process it.
*/
process_single_widget();
}
else {
/*
* We don't have exactly 1 widget, something has gone horribly
* wrong. It's a good thing we checked the result so we can
* detect this error.
*/
fprintf(stderr, "Horrors, we have %d widget(s)\n", result);
exit(EXIT_FAILURE);
}

If the error escapes code review, it won't show up until
something goes horribly wrong and the program calls
process_single_widget() anyway.

Personally, I think the best solution is to make sure your code
is written and reviewed by people who know the difference
between "=" and "==". (Yeah, that's glib; I'd also require
programmers to pay attention to warnings.)

Actually, the *best* solution is to hop into a time machine and
tell Dennis Ritchie to use "=" for equality and ":=" for
assignment, or something similarly distinctive. It's a pity
that time machines invoke undefined behavior (real demons, real
noses).

A syntax that doesn't look like an equation would be even harder
to screw up.

store(x, 12);
 
J

James Antill

The expression isn't unclear /at all/, and only an expert could have the
slightest doubt about it. :)

Well personally find...

if (i == 1) {}
if ((i = 1)) {}

....much more readable/clear over...

if (1 == i) {}
if (i = 1) {}

....which is possibly what Richard meant, but then I quite happily _don't_
ignore warnings that my compiler gives me so I've never seen any advantage of
the later. And the former catches the problems the later doesn't.
 
R

Richard Heathfield

[Got to love KNode. Its random crashes are so damn nostalgic. If this is my
second reply to James, I apologise in advance for that.]

James said:
Well personally find...

if (i == 1) {}
if ((i = 1)) {}

...much more readable/clear over...

if (1 == i) {}
if (i = 1) {}

Do you find x == y clearer than y == x? If so, why? If not, why do you find
i == 1 clearer than 1 == i?
...which is possibly what Richard meant, but then I quite happily _don't_
ignore warnings that my compiler gives me so I've never seen any advantage
of the later.

if(i = 1) does /not/ require a diagnostic message, and indeed some
implementations do not issue a diagnostic message for it.
And the former catches the problems the later doesn't.

The extra parentheses do not suppress any required diagnostics, and do not
guarantee the generation of any extra diagnostics. You are relying on an
implementation-specific trick, which is fine, provided you remain locked
into your existing implementation.
 
J

Jeremy Yallop

Richard said:
Do you find x == y clearer than y == x? If so, why? If not, why do you find
i == 1 clearer than 1 == i?

"If Geraldine is seventeen..."
"If seventeen is Geraldine..."

In (most?) natural languages the variable is written first. "is" is
sometimes symmetric ("the morning star is the evening star"), but it's
by no means always so ("Cambridge is in Gloucestershire"); it often
denotes set membership rather than identity. C's equality and
relational operators are similar: (i == 4) and (i < 4) mean (to me)
something like:

i \in {x:x=4}
i \in {x:x<4}

i.e. a test for whether "i" is a member of a certain (statically)
well-defined set. (The question concerns the /current/ value of the
thing on the left, and questions about the current value of an
unchanging quantity are unnatural, to say the least.)

As an aside, this doesn't arise in practice, since I virtually never
use "==" in C. Tests for identity tend to get written using "!=",
tests for null with "if (x)", and tests for equality with switch/case.
Standard library functions that return non-zero values on failure
(time()) or use zero other than to indicate failure (setjmp(),
strcmp()) are probably the only circumstances in which "==" shows up
consistently in my code.

Jeremy.
 
A

Arthur J. O'Dwyer

Do you find x == y clearer than y == x? If so, why? If not,
why do you find i == 1 clearer than 1 == i?

Obviously because one expresses the writer's intent more clearly.
It is a long-standing tradition at least in English-language
mathematical notation to put the variable on the left and the
value on the right, e.g.

If a \coprime p, then a^(p-1) \congruent 1 (mod p)

as opposed to the relatively sillier-looking

If a \coprime p, then 1 \congruent a^(p-1) (mod p)

As with other mathematical and scientific conventions, this one
has carried over into programming. Possibly also a factor is
the English grammatical pattern

"_He_ is Bob." answers the question "Who is _he_?"

"_X_ equals 1." answers the question "What is _X_?"

"1 equals _X_." seems to answer the question "What is 1?",
which is intuitively perceived as silly, since everyone (except
maybe a few experts ;-) already knows what 1 is -- it's 1!

I don't know of any languages that do the he-is-bob pattern
differently, so I'm confident that it's fairly universal.

-Arthur
 
K

Keith Thompson

Arthur J. O'Dwyer said:
I don't know of any languages that do the he-is-bob pattern
differently, so I'm confident that it's fairly universal.

<YODA>Bob he is, hmmm?</YODA>

if (1 == x) reads (to me) like Yodaspeak.
 
R

Richard Heathfield

Arthur said:
Obviously because one expresses the writer's intent more clearly.

Hmmm. If it's "obvious", how come I don't see it?
It is a long-standing tradition at least in English-language
mathematical notation to put the variable on the left and the
value on the right, e.g.

It's a long-standing tradition, at least in English-language mathematical
notation, for:

i = i + 1

to have no real solutions. But programmers don't hesitate to discard that
baggage when it suits them.

Possibly also a factor is
the English grammatical pattern

"_He_ is Bob." answers the question "Who is _he_?"

This isn't the same concept as "is /this/ scalar value the same as /that/
scalar value?".
"_X_ equals 1." answers the question "What is _X_?"

It is just as valid IMHO to say that it answers the question "is the value
of _X_ equal to 1?"
"1 equals _X_." seems to answer the question "What is 1?",

See above.
which is intuitively perceived as silly, since everyone (except
maybe a few experts ;-)

already knows what 1 is -- it's 1!

But does it have the same value as X? I think we should be told.
I don't know of any languages that do the he-is-bob pattern
differently, so I'm confident that it's fairly universal.

I don't know of any conforming C compilers that don't issue a diagnostic for
if(1 = x), so I'm confident that it's fairly universal.
 
R

Richard Heathfield

Jeremy said:
"If Geraldine is seventeen..."
"If seventeen is Geraldine..."

<shrug> C is not English. In this case, by the way, it would be a rather
more accurate comparison if you were to write: "if seventeen is Geraldine's
age" and "if Geraldine's age is seventeen". In C:

if(girl->age == 17)

and

if(17 == girl->age)

In (most?) natural languages the variable is written first. "is" is
sometimes symmetric ("the morning star is the evening star"), but it's
by no means always so ("Cambridge is in Gloucestershire");

But that's a different question anyway (as I know you realise).
it often
denotes set membership rather than identity.

I think you'll find that the == operator denotes equality, not set
membership.

<snip>
 
R

robin.pain

Are you still living in the 19th century? This has been discussed millions
of times.

"If I've told you once, I've told you a million times, avoid hyperbole."

W.Saffire
 
P

Preben Traerup

[snip]
The compiler may only produce a waring: "Possibly incorrect
assignment", but we may ignore it. To avoid such a mistake,
just reverse the two identifiers.
For gcc add -Werror
and learn to fix stuff the hard way.

I said gcc and I became OT - sorry.
 
J

Jeremy Yallop

Richard said:
<shrug> C is not English. In this case, by the way, it would be a rather
more accurate comparison if you were to write: "if seventeen is Geraldine's
age" and "if Geraldine's age is seventeen".

I don't want to belabour the point, but the former still sounds
unnatural to me.
I think you'll find that the == operator denotes equality, not set
membership.

It denotes value equality, yes, but a variable is not the same /kind/
of thing as a literal, which is why most people do not find "if (x == 1)"
and "if (1 == x)" equally readable, whichever they prefer.

Jeremy.
 
O

ozbear

A syntax that doesn't look like an equation would be even harder
to screw up.

store(x, 12);

Oh really? What does:

store (a,b);

mean to anyone? Store the contents of a into b or the other way
around?

Oz
 
G

goose

A syntax that doesn't look like an equation would be even harder
to screw up.

store(x, 12);

even better, use memcmp() for all equality comparisons
of integers, and have all magic numbers as constant variables.

goose,
more typing, less haste ... or somethinglike that
 
A

Arthur J. O'Dwyer

Hmmm. If it's "obvious", how come I don't see it?

Don't ask _me_. :)
It's a long-standing tradition, at least in English-language mathematical
notation, for:

i = i + 1

to have no real solutions. But programmers don't hesitate to discard that
baggage when it suits them.

Not really. The = sign in mathematics just means something slightly
different than it does in C. If you want Pascal or BASIC, you know
where to find them. (The mathematical = relation is equivalent to the
C == operator, and indeed in C (i == i+1) has no solution for
unsigned integral i.)

This isn't the same concept as "is /this/ scalar value the same as /that/
scalar value?".

Sure, it is. Except for the use of names and people instead of variables
and values, of course. And of course I'm not arguing for any particular
ordering of different variable names or values; (x==y) and (y==x) behave
exactly the same, out of context. I'm merely pointing out that (x==1)
and (1==x) -- variable-to-value comparisons -- have different semantic
content.

It is just as valid IMHO to say that it answers the question "is the value
of _X_ equal to 1?"
True.


See above

....where, by analogy, we have "is the value of 1 equal to _X_?" That's
just as silly; you've just added more words to the question.

But does it have the same value as X? I think we should be told.

In the mathematical sense, who cares? We already _know_ what 1 is,
and what it means. We're usually interested in solving for _X_;
finding out what _X_ is.
I don't know of any conforming C compilers that don't issue a diagnostic for
if(1 = x), so I'm confident that it's fairly universal.

ITYM you're confident that the construct is *not* universal,
but the [required] diagnostic is. I think you're right.

-Arthur
 

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

No members online now.

Forum statistics

Threads
474,083
Messages
2,570,591
Members
47,212
Latest member
RobynWiley

Latest Threads

Top