это заставило меня задуматься, все ли переменные хранятся смежно в том порядке, в котором они объявлены.
Нет, или, по крайней мере, язык не определяет его (см. Франсуа Андрие ответ ). Расположение переменных в памяти (в частности, переменных, не являющихся членами в стеке) зависит от усмотрения компилятора. Поскольку компилятор должен обрабатывать требования архитектуры, такие как выравнивание, он может переставлять переменные и оставлять пропуски между ними. Это может быть важно для оптимизации.
Вот пример (x86-64), где компилятор (clang-9) не размещает переменные в порядке объявления ...
#include <iostream>
int main() {
char a[] {'a', 'b'};
int x;
std::cout << "&a[0] = " << (void*) &a[0] << std::endl;
std::cout << "&a[1] = " << (void*) &a[1] << std::endl;
std::cout << "&x = " << &x << std::endl;
return 0;
}
&a[0] = 0x7ffd5becf02a
&a[1] = 0x7ffd5becf02b
&x = 0x7ffd5becf024