#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define COUNTS 1000000
int f2()
{
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
perror("clock_gettime");
return 1;
}
srand(ts.tv_nsec);
int num;
do
{
num = (int)((double) (rand() / ((double)RAND_MAX + 1.0))*5) + 1;
} while (num == 3);
return (num > 3) ? 1 : 0;
}
int f3()
{
printf("a. %dn",(f2()<<2 + f2()<<1 + f2()));
printf("b. %dn",((int)(f2()<<2) + (int)(f2()<<1) + (int)f2()));
return ((int)(f2()<<2) + (int)(f2()<<1) + (int)f2());
// return (f2()<<2 + f2()<<1 + f2());
}
int main()
{
for (int i = 0; i < COUNTS; i++)
{
f3();
}
return 0;
}
When I run the program above, it will print
a. 8
b. 3
a. 0
b. 6
a. 16
b. 1
a. 16
b. 1
a. 0
b. 6
a. 0
b. 6
a. 32
b. 0
a. 32
b. 4
a. 32
b. 6
a. 0
b. 0
a. 16
b. 7
a. 16
b. 5
a. 0
b. 4
a. 8
b. 6
a. 8
b. 1
a. 32
b. 3
a. 16
b. 7
a. 0
b. 7
a. 0
b. 2
a. 16
b. 2
a. 32
b. 6
a. 0
b. 6
a. 0
b. 3
a. 0
b. 1
a. 8
b. 4
a. 0
b. 2
a. 16
b. 4
When I run the above program, the print is as follows. I ensure that the f2 function returns only 0 and 1, and after calling the f2 function, perform bitwise operations. Why does the first printf print 16 and 32, even if f2 returns 1 for all, the maximum value should only be 7? The return value of the second printf looks correct. Why is this
The platform I am on is Ubuntu 20.04
I want to know if such a result has occurred
2
Answers
If you turn warnings on, the compiler will tell you (at least mine does):
It’s a precedence problem! The addition happens before the bit shift. Use parentheses to fix it.
Because shift operators and arithmetic operators have different precedence when no parentheses are specified. In fact in the
printf()
.b
the values you can observe are in the range [0,7].This is a reference on the precedence given to operators.
I recommend that you enable all compiler warnings and errors and use a debugger to step through your code.
When you get unexpected behavior, the first thing you need to do is make the code output reproducible. In this case you should eliminate
rand()
, which generates pseudorandom numbers, to be able to find the problem, or change its usage, as in the following code.A playground example with explicit parentheses. This is your code slightly modified to allow you to compare the two
printf()
s, and see how the compiler groups the operands.The interested code: