What exactly does the Arduino preprocessor do?
It does four things, basically:


It adds #include &lt;Arduino.h&gt; to the top of your file, which gives you access to all the classes, functions and defined variables/macros of the API.
It joins together all the INO files together into a single monolithic file (in the same order as the tabs in the window),
It matches #include entries with libraries and adds the files in those libraries to the list of files to compile, and
It scans through the ino file(s) looking for functions and adds prototypes to them to the top of your file.


It's the latter that can cause problems. Historically it never got the prototypes in the right place, and if you ever passed a structure of your own devising to a function it would break horribly.  It does a better job these days, but it's still not 100% perfect.

It basically means that you don't have to adhere to the "You must define it before you use it" rule of C/C++.  Which of course makes for lazy programmers.