2

Let's take the following program (called charco.cpp and intentionally starts with //):

//
#include <iostream>
#include <stdio.h>
int main()
{
    FILE* fp = fopen("charco.cpp", "rt");
    char c = fgetc(fp);
    if(c == '/')
    {
        char c2 = fgetc(fp);
        if(c2 == 122^85) // *** OK
        {
            c2 = fgetc(fp);
            while(c2 != 246^252)  // **** NOT OK
            {
                c2 = fgetc(fp);
            }
        }
    }
}

In its current incarnation it will loop forever in the line indicated with **** NOT OK, because it will fail to match the endline character after the // so it reads the entire file...

However, if I change 246 ^ 252 to 10, (char)(246 ^ 252) or just simply '\n' it does not loop forever anymore, it matches correctly, but (char)246^252 fails again.

Can anyone explain me why is this strange behaviour? (compiler: g++ 4.9.2)

Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167

2 Answers2

16
while (c2 != 246^252)

You are doing:

while ((c2 != 246)^252) // Fail, bool^252

if c2 != 246, this will give 253 (0^252). Otherwise will give 252.

You have to use parenthesis :-)

while (c2 != (246^252)) // Correct, c2 != 10
amchacon
  • 1,891
  • 1
  • 18
  • 29
  • For reference (to the OP) see e.g. [this operator precedence table](http://en.cppreference.com/w/cpp/language/operator_precedence). – Some programmer dude Feb 24 '15 at 14:48
  • [Here's an attempt](http://stackoverflow.com/questions/17369090/operator-precedence-table) I once made of a C11 precedence table. – Lundin Feb 24 '15 at 14:54
  • Yup ... This also explain why `(c2 == 122^85)` although that it gives a very weird value is executed correctly ... – Ferenc Deak Feb 24 '15 at 14:54
  • @Lundin I'll print it and stick it on the wall as reminder of this day .. and actually I have looked at the operator precedence table ... just didn't spot the spot :( – Ferenc Deak Feb 24 '15 at 14:57
  • @fritzone Only true C nerds know the operator precedence of every single operator in the language :) Which is why an extra parenthesis is always encouraged as good programming practice. Even if _you_ know the operator precedence of some particular operators, the person reading your code may not. Even the creator of the C language [recognized early on](http://www.lysator.liu.se/c/dmr-on-or.html) that the operator precedence of == would be a cause of trouble. It is kind of a design flaw of C. – Lundin Feb 24 '15 at 15:08
5

For historical reasons, the bitwise operators have a weird operator precedence.

You have to use parentheses to enforce the correct order:

while (c2 != (246^252))

In fact, I strongly recommend using parentheses all the time when you use these operators.

Here's a minimal example to show the difference:

cout << (1 == 1 ^ 2) << " " << (1 == (1 ^ 2)); 
// 3 0
Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • I'd like to see those historical reasons :) – Ferenc Deak Feb 24 '15 at 14:55
  • 1
    I'm just trying to find a good article.. basically initially the bitwise operators were used for logic operators and the actual logical operators were added later to the language, but by that time they wouldn't want to fix the precedence - too much code was relying on the precedence order. – Karoly Horvath Feb 24 '15 at 14:57