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.


Solution 1:

one useful construct is for example:

char *pBuffer;
if (pBuffer = malloc(100))
{
    //continue to work here
}

edit:
as mentioned before, and downvoted several times now, I might add this is not specially good style, but seen often enough to say it's useful. I've also seen this with new, but it makes more pain in my chest.

another example, less controversial, might be:

while (pointer = getNextElement(context))
{
    //go for it, use the pointer to the new segment of data
}

which implies that the function getNextElement() returns NULL when there is no next element so that the loop is exited.

Solution 2:

Most of the time, compilers try very hard to remain backward compatible.

Changing their behavior in this matter to throw errors will break existing legit code, and even starting to throw warnings about it will cause problems with automatic systems that keep track of code by automatically compiling it and checking for errors and warnings.

This is an evil we're pretty much stuck with atm, but there are ways to circumvent and reduce the dangers of it.

Example:

   void *ptr = calloc(1, sizeof(array));
   if (NULL = ptr) {
       // some error
   }

This causes a compilation error.

Solution 3:

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

x = y; if (x) ...

you can write

if (x = y) ...

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:

if ((x = y) != 0) ...

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:

p = malloc(4711); if (p != NULL) printf("Ok!");

The comparison to NULL is redundant, so you can rewrite it like this:

p = malloc(4711); if (p) printf("Ok!");

But since the assignment operation has a value, which can be used, you could put the entire assignment in the if condition:

if (p = malloc(4711)) printf("Ok!");

This does the same thing, but is more concise.