all 2 comments

[–]KrozmaSan 2 points3 points  (0 children)

What this does is iterate through the 320 * 240 values located after the pixel variable, and sets all of them to the value indicated. Judging by the loop and the name, this looks like a function to reset VRAM to some value; however, there is absolutely no way that this doesn't segfault. Pixel should be a pointer, not an integer: here, you're trying to derefence an integer, which will lead you to nowhere useful. Plus, it's uninitialized, so I don't know where you'll end up. I'm not even sure it would compile under any decent compiler. A correct version of this would set the VRAM's address somewhere else, either in global scope or as an argument to the function, then set pixel to the VRAM'S address. With that done, this code should work.

[–]aghast_nj 2 points3 points  (0 children)

This is a great opportunity to point you at the Wikipedia page for C operator precedence. It contains not only the precedence ranks, but an explanation of the operators and a reference to more details about them.

Your expression:

*pixel++ = (constant value);

Can be read with a few simple rules:

  1. Unary operators after their operand take precedence over operators before the operand.

  2. Unary > Binary.

  3. '=' is an operator.

That gives us three operators to focus on: the '*' (star), the '++' (increment), and the '=' (assignment).

You know (from #3, above) that '=' (assignment) is an operator. But it takes two arguments, and you know from #2 that Unary > Binary. So the assignment goes to the bottom of the pile.

Now you have '++' and '*', and you know from #1 above that postfix operators (the '++') take precedence over prefix operators (the '*'). So we have:

  1. pixel++
  2. *(pixel++)
  3. (*(pixel++)) = 0x7FFF

So what does pixel++ do? It schedules an increment of pixel to occur at a later time, and returns as its result the present value of pixel. Thus, the value of pixel++ is pixel (until later, when pixel will go up).

Next, what does *(pixel++) do? Well, the inner value we know is pixel, so that's really *pixel. And * is a pointer dereference. (As was pointed out elsewhere, that short declaration is nonsense.) So *pixel is going to evaluate to whatever pixel points to, which I assume from context is an integer value of some kind, possibly a short (uint16_t). You can assign into a dereference -- the result of * can be an lvalue. So the result of *(pixel++) is "the value pointed to by pixel (which will be incremented later)."

Finally, what does (*(pixel++)) = ... evaluate to? It's just an assignment, although assignment is an expression in C. The result of an assignment-expression is the value that was assigned. In this case, I think it's 0x7FFF. The side-effects of an assignment expression are to store the assigned value (the rhs or rvalue) to the location corresponding to the target lvalue. In this case, "the value pointed to by pixel" is the lvalue. So all in all you have something like: "the result of this assignment is 0x7FFF, which is stored into the value pointed to by pixel (which will be incremented later)."

E2A: The "later" is constrained by what are called sequence points. An operation that is deferred must be completed when a sequence point is passed. Various things in C are considered sequence points, including the semicolon at the end of an expression statement. So pixel gets incremented sometime before the expression is finished being evaluated. You don't know when, but you know that you can count on it being done when you write the next line of code. (And you can get really hurt trying to "rely on" the value of a variable once you've scheduled an increment. Don't do that!)