It seems that
if (x=y) { .... }
instead of
if (x==y) { ... }
is a root of many evils.
Why don't all compilers mark it as error instead of a configurable warning?
I'm interested in finding out cases where the construct if (x=y)
is useful.
Simple answer: An assignment operation, such as x=y, has a value, which is the same as the newly assigned value in x. You can use this directly in a comparison, so instead of
you can write
It is less code to write(and read), which is sometimes a good thing, but nowadays most people agree that it should be written in some other way to increase readability. For example like this:
Here is a realistic example. Assume you want to allocate some memory with malloc, and see if it worked. It can be written step by step like this:
The comparison to NULL is redundant, so you can rewrite it like this:
But since the assignment operation has a value, which can be used, you could put the entire assignment in the if condition:
This does the same thing, but is more concise.
Try viewing
as
The compiler won't flag it as an error because it is valid C/C++. But what you can do (at least with Visual C++) is turn up the warning level so that it flags it as a warning and then tell the compiler to treat warnings as errors. This is a good practice anyway so that developers don't ignore warnings.
If you had actually meant = instead of == then you need to be more explicit about it. e.g.
Theoretically, you're supposed to be able to do this:
to override the warning, but that doesn't seem to always work.
Standard C idiom for iterating:
I, personally, consider this the most useful example.
Say that you have a function
read()
that returns the number of bytes read, and you need to use this in a loop. It's a lot simpler to usethan to try and get the assignment out of the loop head, which would result in things like
or
The first construct feels awkward, and the second repeats code in an unpleasant way.
Unless, of course, I've missed some brilliant idiom for this...
Like most languages, C works inner-most to outermost in order by operator precedence.
First it tries to set k to 1, and succeeds.
Next: it sets k to 2, and succeeds.
Next: it evaluates (true || true)
Finally, it then resolves the conditional: If (true)
In nearly 30 years of programming I have not seen a valid reason for using this construct, though if one exists it probably has to do with a need to deliberately obfuscate your code.
When one of our new people has a problem, this is one of the things I look for, right along with not sticking a terminator on a string, and copying a debug statement from one place to another and not changing the '%i to '%s' to match the new field they are dumping.
This is fairly common in our shop because we constantly switch between C and Oracle PL/SQL; if( k = 1) IS the correct syntax in PL/SQL.