What does (int_1 += *pointer++ = int_2++) < int_3 mean?
Asked Answered
P

2

4

I was reading this earlier answer which had a piece of C code I couldn't understand. It essentially looks like this:

if((int_1 += *pointer++ = int_2++) < int_3) continue;

I can break it down to something like this -

What does this mean? I can get up to about this point:

if((int_1 = int_1+ *pointer++ (unsure about this part))<int_3) continue;
Psychokinesis answered 15/3, 2017 at 21:23 Comment(6)
As an FYI, this would not be "expert syntax." This would be "highly obfuscated, poorly-written syntax designed to confuse you." :-)Carillonneur
@Carillonneur You beat me to almost the same comment!Crossexamine
May I ask you why? Why would you want to understand that horrible syntax?Crossexamine
@IharobAlAsimi I am trying to understand the answer here - https://mcmap.net/q/1332972/-generating-all-distinct-partitions-of-a-number and I don't have enough reputation to commentPsychokinesis
Yes! See my answer. :-)Carillonneur
@Carillonneur Thanks a lotPsychokinesis
C
11

So for starters, this is really, really bad C code. Like, horrible C code. Like, I've been coding in C for a long time and had to pull up an operator precedence chart because I've never encountered something like this terrible. So there's no reason to write something like this - certainly not in production code, and hopefully not as part of a class because you shouldn't never need to know this particular quirk of operator precedence (source: I teach CS for a living). I would go so far as to say that the source that you're referencing is Bad C Code That Should Never Be Written That Way.

But with that said, let's break it down! The core expression here is

(int_1 += *pointer++ = int_2++) < int_3

In that inner expression are two assignment operators, which have equal precedence and group from right-to-left. That means this is equivalent to

(int_1 += (*pointer++ = int_2++)) < int_3

This means

  1. Increment int_2 and store its old value.
  2. Store that value at the place pointed at by pointer, then advance pointer to the next location.
  3. Add that value to int_1.
  4. Then see whether that value is less than int_3.

There's no reason to do something like this. Just write

int val = int_2;
*pointer = val;
int_1 += val;

int_2++;
pointer++;

if (int_1 < int_3) {
    ...
}

So yeah! Don't write code like this. Ever. :-)

Carillonneur answered 15/3, 2017 at 21:31 Comment(7)
This reminds me of an employer I worked for in the late-80's/early-90's who had a piece of software which A) was critical to the functioning of the business, B) was undocumented, and C) they had lost the source to. Solution: rather than figure out what it did, and how, they just kept calling "the magic function", happy to know that it did something even if they weren't quite sure how. This is a Fortune 1000 company, BTW... :-)Jabe
Bad code, poorly addressed? No wonder it's Fortune 1000 rather than Fortune 500. :-)Carillonneur
It's actually clearer by avoiding val: *pointer = int_2; int_1 += int_2; int_2++; pointer++; if (int_2 <= int_3) { ... } Nephridium
I'd rather call it "fortunate". But maybe it just is suicidal, hoping the platform it was compiled for will always be available.Homosexual
IBM mainframe running MVS. Although many-times renamed, it's The O/S The Wouldn't Die. Or, who knows? Maybe by now they've reverse-engineered it and having it running on an iPhone... :-)Jabe
The code may be wrong? if (val < int_3) should be if (int_1 < int_3)Daviddavida
@RandyLai Good catch! Fixed.Carillonneur
C
4

Let's work from the outside, in:

if (...) continue;

This is an if-statement, with a single statement (continue) as its body.

The continue statement is only valid within a loop. So, somewhere there is a loop - either for or do ... while or while - and this statement is inside it.

If the condition is true, whatever that is, the continue will cause the execution of body of the loop to skip forward to the end of the loop body, evaluate the condition of the loop, and possibly increment and start the next iteration (depending on the loop guard, and whether there's a for loop with a non-empty increment).

Now let's look at the inside:

(int_1 += *pointer++ = int_2++) < int_3

This is a parenthesized expression being compared with int_3. So we have something like:

temp < int_3

This is a conditional expression, being used inside an if statement, so you can figure out how that's going to work.

The parenthesized expression looks like this:

int_1 += *pointer++ = int_2++

There are two binary operators in use. The ternary (three arguments) and binary (two arguments) have lower precedence than the unary (one argument) operators. So the = and += will be evaluated "last"-ish. In fact, the assignment operators are right-associative

This means that in a scenario like this one, given A = B = C (where = can also be +=, or %= or whatever), the expression will be arranged as if it were:

A = (B = C)

Grouping to the right, instead of to the left as with + and *, where A+B+C becomes (A+B)+C.

So your inner expression is going to be separated into two parts:

   int_1 +=              (   *pointer++ = int_2++  )

Now the right-hand part will be evaluated first:

*pointer++ = int_2++

There is a pointer-dereference (*) operator, and two post-increment operators.

The post-increment operator evaluates to the current value of whatever you are applying it to, but then causes that value to be increment after evaluation. So int_2++ is really something like this:

(temp = int_2, int_2 = int_2+1, temp)

Likewise, saying *pointer++ = value really means this:

*pointer = value
pointer = pointer + 1

So you have the target of the present value of the pointer being assigned to the present value of int_2, and then both of them are incremented afterwards.

C defines its assignment operator to return the rvalue of the assignment. That is, to return the value that was stored into whatever lvalue is on the left side of the assignment operator. In this case, the = assignment will return the present value (before post-increment) of int_2.

So you have the final part of your expression:

int_1 += ...

Knowing that the value on the right (the rvalue) is going to be the present value of int_2, your code is adding that value to int_1. C's += operator is a shorthand: L += R is the same as L = L + R except it only evaluates L one time. So the end result is that something like int_1 = int_1 + int_2 gets executed.

You will recall that assignment operators return their assigned value. The same is true for special assignment operators. In this case, the result of the += will be the left side of the A < B comparison that makes up your if statement.

If we knew what int_1 and int_2 were, we could decide if that was going to be < int_3, if we knew what int_3 was. ;-)

Complaint answered 15/3, 2017 at 21:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.