Общепринятой практикой является объявление переменных стека (переменных, размещенных в исполняющем стеке, а не динамически или статически) в точке входа функции, а не в сочетании с инструкциями внутри функции. См. примеры 1.а и 1.б. Это помогает улучшить читаемость и было даже необходимо для более старого языка.
С современным C/C++ это больше не требуется (... но все же хорошая практика).
Мой вопрос, хотя: Как компилятор решает эту проблему, если переменные стека находятся внутри функции, а не в точке входа. См. примеры 2.a и 2.b, как я могу себе представить, как он это решает. Что НА САМОМ ДЕЛЕ ПРОИСХОДИТ?
1.a) Example (Common Practice / Best Practice)
void main()
{
int a = 3; // best practice
bool c = false; // best practice
a += 16;
if (a == 5)
{
c=false;
}
}
...скорее, чем ...
1.b) Example (Uncommon)
void main()
{
int a = 3;
a += 16;
bool c = false; // variable after some instructions executed..
if (a == 5)
{
c=false;
}
}
2.a) Possible compiler solution (A)
void main()
{
int a = 3;
a += 16;
bool c = false; // COMPILER CUTS THIS LINE AND MOVES IT UP UNDER "int a = 3;"
if (a == 5)
{
c=false;
}
}
2.B) Possible compiler solution (B)
void main()
{
int a = 3;
a += 16;
{ // COMPILER ADDS SUBSECTION IN ORDER TO INTRODUCE NEW VARIABLES ON STACK
bool c = false;
if (a == 5)
{
c=false;
}
}
}





Когда, как и где компилятор создает или выделяет такие переменные, полностью зависит от реализации. Он может создать кадр стека для всех переменных в начале функции, или он может расширить кадр стека в точке объявления, или он может вообще не использовать стек и вместо этого использовать регистровое хранилище.
Язык требует только реализации правильной семантики; что переменная не является в рамках (т. е. на нее нельзя ссылаться в коде) до того, как она будет объявлена, и что область действия заканчивается после закрытия } блока, в котором она была объявлена.