I have worked on projects for embedded systems in the past where we have rearranged the order of declaration of stack variables to decrease the size of the resulting executa
Not only can the compiler reorder the stack layout of the local variables, it can assign them to registers, assign them to live sometimes in registers and sometimes on the stack, it can assign two locals to the same slot in memory (if their live ranges do not overlap) and it can even completely eliminate variables.
As there is nothing in the standard prohibiting that for C or C++ compilers, yes, the compiler can do that.
It is different for aggregates (i.e. structs), where the relative order must be maintained, but still the compiler may insert pad bytes to achieve preferable alignment.
IIRC newer MSVC compilers use that freedom in their fight against buffer overflows of locals.
As a side note, in C++, the order of destruction must be reverse order of declaration, even if the compiler reorders the memory layout.
(I can't quote chapter and verse, though, this is from memory.)
There's no need for idle speculation about what the C standard requires or does not require: recent drafts are freely available online from the ANSI/ISO working group.
A decent compiler will put local variables in registers if it can. Variables should only be placed on the stack if there is excessive register pressure (not enough room) or if the variable's address is taken, meaning it needs to live in memory.
As far as I know, there is nothing that says variables need to be placed at any specific location or alignment on the stack for C/C++; the compiler will put them wherever is best for performance and/or whatever is convenient for compiler writers.
AFAIK there is nothing in the definition of C or C++ specifying how the compiler should order local variables on the stack. I would say that relying on what the compiler may do in this case is a bad idea, because the next version of your compiler may do it differently. If you spend time and effort to order your local variables to save a few bytes of stack, those few bytes had better be really critical for the functioning of your system.
The compiler for the Texas instruments 62xx series of DSP's is capable of, and does "whole program optimization." ( you can turn it off)
This is where your code gets rearranged, not just the locals. So order of execution ends up being not quite what you might expect.
C and C++ don't actually promise a memory model (in the sense of say the JVM), so things can be quite different and still legal.
For those who don't know them, the 62xx family are 8 instruction per clock cycle DSP's; at 750Mhz, they do peak at 6e+9 instructions. Some of the time anyway. They do parallel execution, but instruction ordering is done in the compiler, not the CPU, like an Intel x86.
PIC's and Rabbit embedded boards don't have stacks unless you ask especially nicely.