You don't know the heap layout in C either, at least not without some extreme measures like reading the values of pointers, and you don't usually care.
You can't just say "oh this is sort of like this so we'll just collapse all the differences". Macros change your program logically (as in not just perf improvements) prior to compilation. Not-macros do not. That's a big difference.
That line is crystal clear (as shorthand) to a Java developer because "foos" is most likely an Iterator<Foo> which will throw an exception when there are no more foos. In an actual program it will be very explicit that it's an Iterator<Foo>. That's a context thing that's specific to Java where all Iterators behave the same way. The difference between the standard java.util stuff and macros is that each shop or team has their own macros and in my limited experience with macros, it is not always easy to tell where they're in effect.
And, the line isn't boilerplate. We're creating a reference to a Foo and assigning a value to the destination of that reference. Presumably, we're going to do some stuff with it later. Otherwise, yes, we would not be bothering to pop one out of the iterator. Is that clear now? What actual point are you trying to prove in this comment? My comment was sort of a request for actual constructive solutions. You've provided non-sequitors.