Double equals in C

Thread Starter

Ian0

Joined Aug 7, 2020
10,276
I was just wondering what benefits the == test for equality bring to the C language over the single = that other languages (Basic, for instance) use.
 

WBahn

Joined Mar 31, 2012
30,303
I was just wondering what benefits the == test for equality bring to the C language over the single = that other languages (Basic, for instance) use.
A number of languages use == for equality comparison to disambiguate it from = for assignment. Other languages use a different symbol, such as := or -> for assignment.

In some languages, this is not necessary because the two operators can't be used in each other's contexts, but in C that is very much not the case.

For instance, you can do things like:

areEqual = a == b;

But

x == y = b

is also valid syntax.

A common place where this is leveraged is in loop and validation checks.

For instance

Code:
if (fp = fopen(filename, mode))
   // The file opened successfully
else
  // The file failed to open
To be sure, however, it is a common source of logic errors, such as

if (x = 5)

when

if (x == 5)

what meant.

Most compilers will issue a warning about use of assignment when equality comparison was likely intended. Unfortunately, too many "programmers" routinely ignore warnings without even glancing at them.

Where possible, such as when comparing for equality between something and something else that is not an lvalue, put the something else on the left site. For example

if (5 == x)

Because now, if you make the mistake and use = instead of ==, you have made a syntax error.

Years ago I has a student that came in the day that an assignment was due (and that they had had two weeks to work on) who hadn't bothered paying attention in class as I went over, several times, how to open files and check for success. But she had at least grasped the notion that failing to verify that a file opened successfully was one of the things that would lose 50% of the points right off the bat.

So I showed her how to do that with the following code.

Code:
fp = fopen(filename, mode);
if (NULL == fp)
   exit(EXIT_FAILURE);
I explained exactly what everything did, and why the if() test was written with the NULL pointer on the left side, stating in minute detail how if you did it the other way around and forgot to use the == and used the = instead, that you would overwrite the file pointer with a NULL pointer, which would then fail the test, so the program would not abort, which would then guarantee that your first file operation would dereference a NULL pointer and crash the program.

She remarked that it looked awkward, which I admitted, but told her that it would save her a lot of grief if she got in the habit of doing it.

She went away and came back three hours later complaining that her program kept crashing. She had the entire program (supposedly) written, amounting to a couple pages of code and, right near the top, was

Code:
fp = fopen(filename, mode);
if (fp = NULL)
   exit(EXIT_FAILURE);
Not only had she not bothered to test her code incrementally, as I preached incessantly, but she had made the very mistake that I had very explicitly warned her about.

It was really hard for me to develop much sympathy for her. Instead, I explained that programming is both an art and a science, the art is learning from your own mistakes, while the science is learning from the mistakes of others. I told her that I had done everything I could think of to help her practice the science of programming, but that she had, instead, opted to practice the art.

EDIT: Added code brackets to preserve indenting.
 
Last edited:

Thread Starter

Ian0

Joined Aug 7, 2020
10,276
I suppose that in order to answer my question, I would first have to understand the advantages of doing an assignment as part of a conditional test. So far, I have only seen that as a way of creating confusion between assignment and equality test.
 

nsaspook

Joined Aug 27, 2009
13,560
I suppose that in order to answer my question, I would first have to understand the advantages of doing an assignment as part of a conditional test. So far, I have only seen that as a way of creating confusion between assignment and equality test.
I do assignments during conditional tests as a shortcut (test and assign) to save the result (usually from a function) for later possible use.
It can avoid avoid excessive nesting.

C:
if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}
 

MrChips

Joined Oct 2, 2009
31,087
I was just wondering what benefits the == test for equality bring to the C language over the single = that other languages (Basic, for instance) use.
Big difference. This is a common programming error that you don't want to make.
 

WBahn

Joined Mar 31, 2012
30,303
I suppose that in order to answer my question, I would first have to understand the advantages of doing an assignment as part of a conditional test. So far, I have only seen that as a way of creating confusion between assignment and equality test.
I gave an example.

Another example is reading characters from a stream one at a time until a specific value is encountered. You need to assign the value to a variable and then check if the value is equal to the character you are looking for as your terminating condition. You need to read the value before the first test, but also read it as part of each loop. By combining these in one test condition, it reduces the footprint for errors when copying/modifying code.

For instance, if you are reading characters via some function that returns NUL when the stream is finished, you turn:

Code:
c = readchar();
while (c)
{
   // Do whatever with c
   c = readchar(); 
}
into

Code:
while (c = readchar())
{
   // Do whatever with c
}
This has the same advantage as the for() loop in that it parks all of the loop housekeeping in one place.

If you are looking for something other than the NUL, such as the end-of-line character, this becomes:

Code:
while ('\n' != (c = readchar()))
{
   // Do whatever with c
}
Note that the parens around the assignment expression are necessary because assignment is lower precedence than relational operations.
 

WBahn

Joined Mar 31, 2012
30,303
Another advantage that hasn't been mentioned, although one that is becoming less relevant today, is performance. By coding the assignment within the test, simple compilers can produce more optimized code, which can still be important in resource-starved environments. With today's processor capabilities and the smarts of today's major compilers, this is less of the advantage that it used to be.
 

MrChips

Joined Oct 2, 2009
31,087
Just remember that single = is an assignment.
Double equal == is a comparison whose result is boolean TRUE or FALSE. The test is usually a subtraction followed by a check of a zero flag.
 

ApacheKid

Joined Jan 12, 2015
1,675
I was just wondering what benefits the == test for equality bring to the C language over the single = that other languages (Basic, for instance) use.
It's easy to parse, no benefit to the programmer, take a look at Javascript, there you can use === I can't wait for ==== one day.
 
Last edited:

WBahn

Joined Mar 31, 2012
30,303
It's easy to parse, no benefit to the programmer, take a look at Javascript, there you can use === I can't wait for ==== one day.
It's not because it's easy to parse. The semantics are very different. If it were just a parsing convenience, you could use a single equals sign for both operators and the code would still only have one valid interpretation. But that's not the case, because in many, even most, contexts where you could use one you could use the other and have valid, but semantically different, code. Just because YOU don't like it and don't want to leverage it, does not mean that it has no benefit to the programmer.
 

Thread Starter

Ian0

Joined Aug 7, 2020
10,276
I don’t like it either: it catches me out frequently*. I grew up with BBC Basic, but I didn‘t think that it way that was just because some misanthrope was having a bad day when C got invented.
However, having followed the discussion I don’t see many examples of assignment during a conditional test that are consistent with the writing of clear code. I can see the value when memory was scarcer, processors were slower and compilers weren’t so clever.

* I’m going to try
if (CONSTANT == variable)
to see if I can get it wrong less often, but often it is better to test for
variable>CONSTANT
especially with counters, as that catches any faults where the counter has got out of bounds.
 

ApacheKid

Joined Jan 12, 2015
1,675
It's not because it's easy to parse. The semantics are very different. If it were just a parsing convenience, you could use a single equals sign for both operators and the code would still only have one valid interpretation. But that's not the case, because in many, even most, contexts where you could use one you could use the other and have valid, but semantically different, code. Just because YOU don't like it and don't want to leverage it, does not mean that it has no benefit to the programmer.
Well it is easier to parse, so I suspect that played a role in it being chosen. In the 60s compilers were hard to develop, no tools and often mainly written in assembler.
 

ApacheKid

Joined Jan 12, 2015
1,675
I don’t like it either: it catches me out frequently*. I grew up with BBC Basic, but I didn‘t think that it way that was just because some misanthrope was having a bad day when C got invented.
However, having followed the discussion I don’t see many examples of assignment during a conditional test that are consistent with the writing of clear code. I can see the value when memory was scarcer, processors were slower and compilers weren’t so clever.

* I’m going to try
if (CONSTANT == variable)
to see if I can get it wrong less often, but often it is better to test for
variable>CONSTANT
especially with counters, as that catches any faults where the counter has got out of bounds.
Assignment could simply be a <- b;
 

ApacheKid

Joined Jan 12, 2015
1,675
It's not because it's easy to parse. The semantics are very different. If it were just a parsing convenience, you could use a single equals sign for both operators and the code would still only have one valid interpretation. But that's not the case, because in many, even most, contexts where you could use one you could use the other and have valid, but semantically different, code. Just because YOU don't like it and don't want to leverage it, does not mean that it has no benefit to the programmer.
Bear in mind too, the semantics of a DOT are very different too:

123.456
data.status

But enough, I've expressed my disappointment and frustration with the C grammar several times and I'm not trying to flog a dead horse here.
 

MrChips

Joined Oct 2, 2009
31,087
I don’t like it either: it catches me out frequently*. I grew up with BBC Basic, but I didn‘t think that it way that was just because some misanthrope was having a bad day when C got invented.
However, having followed the discussion I don’t see many examples of assignment during a conditional test that are consistent with the writing of clear code. I can see the value when memory was scarcer, processors were slower and compilers weren’t so clever.

* I’m going to try
if (CONSTANT == variable)
to see if I can get it wrong less often, but often it is better to test for
variable>CONSTANT
especially with counters, as that catches any faults where the counter has got out of bounds.
When testing for limits, you should not test for equality. Use <= and >= instead of ==.
If you are using float or real data types, never use ==.
 
Top