The meaning of a single & in an if statement - c

Came across a weird notation today while reading through some C code
Can anyone explain to me what the line do?
if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}

if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}
& is Binary And Operator. & is applied to every bit of both the variables .It checks ,
if result of dwEvent & EV_RXCHAR is non-zero then cs.cbInQue is checked if it is non-zero or not .
If both the conditions are true code in if block is executed .
if result of dwEvent & EV_RXCHAR is zero then without checking cs.cbInQue , code in else block is executed if present.

It masks (performs binary AND operation) dwEvent with EV_RXCHAR, checks if the result is non-zero, checks if cs.cbInQue is non-zero, if both are true, executes code in conditional statement.
This is not necessarily a "weird" notation. Many programmers use it as a shortcut instead of specifying (x & y) != 0.

It is a bitwise operation. You can read it here. link

Its short form to check if the any of the bits EV_RXCHAR are set by checking getting out those bits first (dwEvent & EV_RXCHAR). Then if any of these are set it
would also check if cs.cbInQue is also set then do the stuff.
eg:
unsigned int x = dwEvent & EV_RXCHAR;
if (x !=0)
if (cs.cbInQue != 0)
{ /* do stuff */}

Related

How does the bitwise AND help in the if statements in the Linux Kernel?

Background on what the code is trying to achieve:
"Various parameters of the new process (e.g., euid, egid, argument list, environment, filename, etc.) that
are subsequently passed to other functions are, for the sake of simplicity, combined into a structure of
type linux_binprm. prepare_binprm is used to supply a number of parent process values (above all, the
effective UID and GID); the remaining data — the argument list — are then copied manually into the
structure. Note that prepare_binprm also takes care of handling the SUID and SGID bits:"
fs/exec.c
int prepare_binprm(struct linux_binprm *bprm)
{
...
bprm->e_uid = current->euid;
bprm->e_gid = current->egid;
if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
/* Set-uid? */
if (mode & S_ISUID) {
bprm->e_uid = inode->i_uid;
}
/* Set-gid? */
/*
* If setgid is set but no group execute bit then this
* is a candidate for mandatory locking, not a setgid
* executable.
*/
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
bprm->e_gid = inode->i_gid;
}
}
...
}
Here, the bitwise AND (&) is being used in the if-statement to analyze the flags. But what does this achieve? As in, what is the condition its checking and how is it evaluated?
Source: Linux Kernel Architecture
The result of bitwise and expression a & b is a number with value 1 at every bit that is set in both a and b, and value 0 at all other bits. If that result is exactly equal to b (for example) then it must be the case that every bit that is set in b is also set in a. If the result is unequal to b then there must be at least one bit set in b that is not set in a.
In your particular example, mode is a file mode bitmask, S_ISGID is a macro representing the set-group-id bit of such a mask, and S_IXGRP is a macro representing the group-executable bit of such a mask. The condition then evaluates whether both the S_ISGID bit and the S_IXGRP bit are set in mode. If a regular file has a mode for which that is the case then that file is a setgid executable.

do ... while macro/function with different conditions

I have the following code:
/* some calculation */
do {
/* data acquire and calculation */
} while (CONDITION);
My condition looks like one of the following:
(( A || B ) && C )
( A && C )
Note that I use these conditions with different statements for A, B and C. However the pre-calculation and everything inside the loop is always the same. I use this block several times in my code and wondered if there is a possibility to put it in a define or in a function to let the code look cleaner.
Is there a nice and reasonable way to achieve the loop with different statements?
I already thought about a function call in a while loop like
while (DoMyLoop( CONDITION, calculationParams ));
But with this solution I wouldn't have the pre-calculation in my one-liner.
How can I get my code block in a nice one-liner (or more if necessary, as long as it's easy to understand and maintain)?
Some additional (maybe irrelevant) information:
In my loop I receive a byte array and depending on the situation I have to loop until a specific bit changes, therefore the A or B.
C is a timeout condition.
Here is some code with variables
unsigned char data[10] = { 0 };
long intervalMS = 0;
/* precalc */
gettimeofday( &stopTimeout, NULL );
gettimeofday( &startTimeout, NULL );
do {
receiveCall( data );
gettimeofday( &stopTimeout, NULL );
intervalMS = (stopTimeout.tv_sec - startTimeout.tv_sec) * 1000 +
(stopTimeout.tv_usec - startTimeout.tv_usec) / 1000;
} while ( (data[0] & 0x01) && intervalMS < 200);
The A part of the condition can also look like ((data[2] & 0x02) || data[3] == 0x12).
What about next solution?
for (precalculation (); CONDITION; somethingWith (calculationParams));
precalculation () is executed once, the CONDITION is evaluated at every iteration and somethingWith (calculationParams) take the place in of the incrementation. The body of the for loop is empty.
Pure C beauty.
Obviously, precalculation and somethingWith (calculationParams) must become a new function.
First of all, please note that do {} while(something) is equivalent to something=true; while something{}. The former saves a bit of extra execution in case you don't want the initialization part.
How can I get my code block in a nice one-liner
There is nothing wrong with your code. } while ( (data[0] & 0x01) && intervalMS < 200); is perfectly clear to me - another C programmer.
You check if the lsb is set and you check a timer interval. The only way this code could be improved would be to explain why you check the lsb - which you can do with a comment (do you check if a number is odd or do you read a bit in bit-field etc).
Now what you can and should do, is to put the whole snippet inside a function and give it a meaningful name. There's the nice one-liner.

C program using inotify help in understanding code

I was referring the man page for inotify and I came across this piece of code
if (event->mask & IN_ISDIR)
printf(" [directory]\n");
else
printf(" [file]\n");
where event is a pointer to struct inotify_event.
I couldn't understand this particular line if (event->mask & IN_ISDIR) and why a bitwise AND is used here.
How was it determined that the bitwise AND is supposed to be used here and nothing else? It was not mentioned in the man page for inotify.
This bitwise AND is masking out a specific bit (IN_ISDIR). It is testing whether or not this one bit is set or not. If this bit is set in event->mask, it evaluates to true.
For example,
#include <stdio.h>
#define FIRST_BIT 1
#define SECOND_BIT 2
#define THIRD_BIT 4
int main() {
int x = 3; /* 3 in binary is 011 */
if ( x & FIRST_BIT )
printf("First bit is set\n");
if ( x & SECOND_BIT )
printf("Second bit is set\n");
if ( x & THIRD_BIT )
printf("Third bit is set\n");
}
will give the output
First bit is set
Second bit is set
From inotify.h:
#define IN_ISDIR 0x40000000 /* event occurred against dir */
This value has only one bit set. (In binary, this is 01000000000000000000000000000000.) A bitwise AND with this (0x40000000) and some variable will evaluate to either 0 (if the variable has a 0 here), or 0x40000000 if the variable has a 1 in the same place. Any non-zero value is considered "true".
Logically, it is testing if the event was from a directory (instead of a file).
A bitwise AND is just an easy (and very common) way to check if a specific bit is set.
The man page is clear that if that bit is set then the event is referring to a directory.

difference between "loop_until_bit_is_set" macro and while() expression

this piece of code in running on ATmega2560, so what is the difference between these two:
while(UCSR0A & 0b00100000 == 0); // check UDRE0 bit if it is 1
and:
loop_until_bit_is_set(UCSR0A, UDRE0);
as you can see this is for UART transmission, but if i use the first one I could't get desired output on terminal, for example if i do printf("Hello world\n"); the actual terminal display is: HeHeHe....... However the latter one works. You can find this piece of code in stdio.h.
== has higher priority than &; also, no need to check for == 0 - you should try
while(!(UCSR0A & 0b00100000));
or rather, using bit macro
while(!(UCSR0A & _BV(UDRE0)));
instead.

"Syntax error, multiple markers at this line"?

I have a while loop in C program which was supposed to wait for system to tweak a single bit (bit0) ON and then continue execution. This bit or "flag" is located in a register (reg1). I have been trying to program this using bitwise & operator for masking my register like this.
unsigned int continue;
while(continue != (reg1 & bit0));
I end up getting an error: "Syntax error, multiple markers at this line, expected ')' before ';' token."
continue is a keyword. You can't use it as an identifier.
Change the name to something else and see if it works:
unsigned int cont = 0; // You also forgot to initialize.
while(cont != (reg1 & bit0));

Resources