C++ code translation and explanation - c++

I have the following c++ code snippet. I have a basic understanding of c++ code.Please correct my explanation of the following code where ever necessary:
for (p = q->prnmsk, s = savedx->msk, j = sizeof(q->prnmsk);
j && !(*p & *s); j--, p++, s++);
What does it contain: q is char *q(as declared) is type of structure MSK as per code.
q->prnmsk contains byte data where prnmask containd 15 bytes.
It is similar for s.
So in the for loop as j decreases it will go through each byte and perform this !(*p & *s) operation to continue the loop and eventually if the condition is not met the loop will exit else j will run till j==0.
Am I correct? What does *p and *s mean? Will it contain the byte value?

Some (like me) might think that following is more readable
int j;
for (j = 0; j < sizeof(q->prnmsk); ++j)
{
if ((q->prnmsk[j] & savedx->msk[j]) != 0) break;
}
which would mean that q->prnmsk and savedx->msk are iterated to find the first occurence of where bit-anding both is not zero. if j equals sizeof(q->prnmsk), all bit-andings were zero.

Yes, you are right. !(*p & *s) means that they want to check if q->prnmsk and savedx->msk don't have corresponding bits set to 1 simultaneously.

Related

What happens due to & operator in the following case?

I have known, '&' as bitwise and as an operator to get memory address of a variable.
What happens in this case of the code?
res = res & (a[i]<[a[i+1]]);
If it is bitwise and , as far as I know the second condition is also checked,
but what if I used logical and instead of it , wouldn't it still be the same?
As first part is (say) false , second parts get checked comes true, but still res remains false.
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
int a[] {1,3,4,2};
int pos = 3;
bool res = true;
for(int i = 0; i < pos; i++)
res &= (a[i] < a[i + 1]);
(Sorry for bad english)
If it is bitwise and , as far as I know the second condition is also checked, but what if I used logical and instead of it , wouldn't it still be the same?
No. Boolean and (written as && or and) has short circuit evaluation - if left part is false right part is not evaluated at all. This allows to write code like this:
if( pointer != nullptr && pointer->value > 100 ) ...
if not short circuit evaluation this code would have UB. For example this code:
if( pointer != nullptr & pointer->value > 100 ) ...
has Undefined Behaviour when pointer is equal to nullptr
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
You cannot, as there is no &&= operator in C++. You can write:
res = res && (a[i] < a[i + 1]);
and that would have short circuit as well and compiler may even be smart enough to stop the loop, though I doubt and it should be expressed explicitly anyway:
bool res = true;
for(int i = 0; res && i < pos; i++)
res = a[i] < a[i + 1];
which does the same, but cleaner and more efficient.
Anyway when you need logical or boolean and you should use one to make your intention clear and avoid unexpected surprises.
Besides the short circuiting issue, If res == 2 then:
res & 1 will return 0 which will be interpreted as false.
res && 1 will return true.
Your question is not clear.
Okay, let's dive into your code.
Your given code is very clear. You are performing bitwise and for pos(3) times. For every loop you are comparing a[i] with a[i+1]. Please note that for the last loop, I mean when variable i becomes 3, then i+1 will be 4. And your array a[] doesn't have a[4]. It only has the last element having index 3.
So for bitwise and operation the value of res isn't predictable as a[4] isn't defined.
Now let's think about logical AND operation. For logical and your expression inside the for loop will once generate a false boolean value for a[i] < a[i+1] as your array a[] = {1,3,4,2}. Here 4>2 not 4<2. Hence it will generate false boolean value and your entire response will be false 'cause you know logical AND will be eventually 0 if one of the operands is false.
I think you have got this.

Understanding a C++ function for reversing a string using ^=

The code below returns a reversed string. For example, it take input "codebyte" and returns "etybedoc".
string FirstReverse(string str) {
for(int i = 0, j = str.length() - 1; i < str.length() / 2; i++, j--)
{
str[i]^=str[j]^=str[i]^=str[j];
}
return str;
}
I am lost as to how this function works:
Why is the ^=-operator being used? It is a bitwise operator but why is it being used here?
Why is str.length() divided by 2 in the for loop?
What is with the alteration of str[i] and str[j]?
I want to work though it with values but I don't know where to begin. The introductory textbook I used did not cover this.
As an answer:
It's a swapping functionality similar to the famous bit-twiddling hacks.
A detailed explanation of this swapping mechanism can be found here.
The length is divided by two because otherwise you would undo every swap and end up with the original string again.
The indices i and j run against each other (from the beginning or end, respectively).

Integer doesn't have the expected value in debugger

Like any normal C++ programmer, when I type this code...
for (int m = 0; m < 3; m++){
for (int n = 0; n < 3; n++){
if (A[m].substr(size,location) == B[n].substr(size,location)){
return false;
}
}
}
I expect the first value of m to be 0 in my iteration. (because I literally declared it as having a value of 0) However, my program was acting a tad funky, so I decided to look at it in the debugger. Interestingly, rather than having a starting value of 0, C++ decided that m should have a starting value of 32767.
Could someone explain to my why and how this could possibly happen?
Ah, templatetypedef was right. Once I stepped over to the next breakpoint its value was initialized. Thanks guys!

No checking condition in for loop C++

char i;
for (i = 1; i < 10, i++;)
{
cout << (i+1) << endl;
}
return 0;
I understand that for loop has the following syntax:
for(initialization; condition; increment)
{
}
As I run the debug, why it never checks the condition and it eventually stops at i = 0?
(Thank you Damien and Andars, I don't know why the "on purpose" statement was removed, but you interpret my question correctly. Could someone explain why the complier skips the condition before the comma, and why the loop stop at i = 0 instead of looping forever? Thanks!)
I believe he is indicating that he wrote the code that way on purpose.
To answer, i++ will always return true. The last value is the value that matters with comma separated statements, so the loop will not stop.
Edit for elaborations:
It isn't simply using a logical or, it disregards what is before the comma and only takes the last value. The value of anything non-zero is considered true, and since i starts at 1, and goes up, it will always be non-zero (until it overflows and wraps back around, which explains why i ends at 0).
If you say:
x = 4, 5, 6;
x will be equal to 6, the last value.
Change
for (i = 1; i < 10, i++;)
to
for (i = 1; i < 10; i++)
Change to
for (i = 1; i < 10; i++) //Notice correct placement of ;
It seems to me also that the code was written incorrectly on purpose. As others have mentioned, the comma operator will discard the value of the i<10 and only i++ will be evaluated as condition. This will return true until i overflows (values only from -127 to 127) and ends up at -1, when i++ will return 0 and the loop exits. Thus the final value for i will be 0.
Because you used the comma operator instead of a semi-colon

What sense could have this code?

I´m studing the code of OpenCV, and I came across the next few lines:
The function´s var are:
CvMat* _err;
CvMat* _mask;
int i, count = _err->rows*_err->cols, goodCount = 0;
for( i = 0; i < count; i++ )
goodCount += mask[i] = err[i] <= threshold; // This line is strange for me
return goodCount;
What does the line I indicated actually do? Because, call me strange, I have never seen anything like that.
For your information:
Yes, the code is working :D
The code is part of the CvModelEstimator2::findInliers function.
That line is evil.
Nevertheless, it assigns 1 to mask[i] if err[i] <= threshold and 0 otherwise.
Then it increments goodCount if the condition holds.
mask[i] = (err[i] <= threshold);
goodCount += mask[i];
So you're confused about this line:
goodCount += mask[i] = err[i] <= threshold;
You can use a C operator precedence table to figure out the order of operations here, but it's fairly unambiguous anyway:
Compare err[i] against threshold. This results in a bool (true or false).
Assign the result to mask[i]. I think the bool will be converted to a number here, which will be 1 for true or 0 for false.
Use the new value of mask[i] (which is the result of the = operator) to increment goodCount (basically, goodCount will end up containing the count of "true" values found in step 1).
To me the most subtle part of that line is the fact that assignment returns a reference to the left-hand side (i.e. the target). This is sometimes seen in a less complex expression like this:
if ((mem = malloc(42)) == NULL)
throw ...
goodCount += mask[i] = err[i] <= threshold;
Mixing assignment and comparison in the same statement is generally a bad idea.
The recommended approach is to (1) know what is the precedence of the involved operators, and (2) split the statement into several ones, to enhance readability.