3

I'm using termcaps and I don't understand what &= means in this example:

term.c_lflag &= ~(ICANON);

Could anyone explain to me how this works?

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
user3165140
  • 63
  • 1
  • 1
  • 2

5 Answers5

10

That's a common way to set a specific bit to 0 in an integer that represents a bitfield.

unsigned a = ...;
// ...
unsigned int mask = 1 << 11;  // mask for 12th bit
a |=  mask;  // set 12th bit to 1
a &= ~mask;  // set 12th bit to 0

Enabling a bit works by bitwise-oring a number with a mask that looks like 000010000.
Disabling a bit works by bitwise-anding a number with a mask like 111101111 (hence the need for ~, which stands for bitwise negation).

Note that there are also other options for managing bitfields:

  • in C++, using std::bitset or even std::vector<bool>
  • in C or C++, using a bitfield struct like

    struct Foo {
       int foo_enabled : 1;
       int bar_enabled : 1;
       // ...
    };
    
Kos
  • 70,399
  • 25
  • 169
  • 233
5

&= means Bit Wise AND and then assign. For example

term.c_lflag = (term.c_lflag) & (~(ICANON))

First, do term.c_lflag & ~(ICANON) then assign to term.c_lflag

Chinna
  • 3,930
  • 4
  • 25
  • 55
2

The code turns off the ICANON bit, as Schwartz explain in comment: the ICANON defines a bit through a mask, e.g. 0x8000 (the ICANON bit is the one having value 1), when you apply the bitwise not operator, ~, all bits are "inverted" and you have (if the values are 16bit wide) 0x7FFF. If you put in bitwise and (&) this value with x, the result is to keep unchanged all bits of x matching a "1" bit in the mask 0x7FFF, and "turn off" the bits of x matching a "0" bit in the mask, which is exactly the ICANON bit in this specific case.

About x &= a, as already explained, it can be considered just syntactic sugar for x = x & a.

ShinTakezou
  • 9,432
  • 1
  • 29
  • 39
1
term.c_lflag = (term.c_lflag) & (~ICANON)
sujin
  • 2,813
  • 2
  • 21
  • 33
1

It is not much different from the operator +=. Just like it term.c_lflag &= ~(ICANON); should have the effect of term.c_lflag = term.c_lflag & (~ICANON); but "in place". You will not create a temporary but instead you will modify term.c_lflag. Please note here & is the bitwise AND operator.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176