Выдержка из статьи:
Крис Касперски ака мыщъх
Борьба с утечками ресурсов и переполняющимися буферами на языковом и внеязыковом уровне
http://www.insidepro.com/kk/155r.shtml
Одним их самых мерзких недостатков языка Си является отсутствие поддержки динамических стековых массивов. Стековая память хороша тем, что автоматически освобождается при выходе из функции, однако выделение стековых массивов "на лету" невозможно и мы должны заранее объявить их размеры при объявлении переменных. В C99 сделаны небольшие подвижки в этом направлении и теперь мы можем объявлять массивы, размер которых задается аргументом, передаваемым функции, однако это не решает всех проблем и к тому же C99 поддерживают далеко не все компиляторы.
В частности, компилятор GCC 2.95 нормально "переваривает" следующий код, а Microsoft Visual C++, увы, нет:
Код:
f(int n)
{
char buf[n];
return sizeof(buf);
}
Листинг 7. Стековые массивы с переменным размером, появившиеся в Стандарте C99.
На самом деле выделять динамические массивы все-таки возможно, однако только в том случае, если компилятор, во-первых, адресует локальные переменные через EBP, а во-вторых, в эпилоге использует конструкцию MOV ESP, EBP вместо ADD ESP, n. К таким компиляторам, в частности, относится Microsoft Visual C++, автоматически переходящий на адресацию локальных переменных через регистр EBP, если в теле функции присутствует хотя бы одна ассемблерная вставка.
Фрагмент одной из таких функций приведен ниже:
Код:
text:00000010 push ebp
text:00000011 mov ebp, esp
text:00000013 push esi
...
text:0000002B sub esp, 400h
...
text:00000034 mov eax, [ebp+var_4]
...
text:00000048 pop esi
text:00000049 mov esp, ebp
text:0000004B pop ebp
text:0000004C retn
Листинг 8. Дизассемблерный фрагмент программы, откомпилированной компилятором Microsoft Visual C++ с максимальной оптимизацией (ключ /Ox).
P.S. Дальше по статье продолжается обсуждение данного вопроса кому интересно.
Трудно понять повысит ли это решение эффективность Форт систем написанных на Си при использовании этой возможности:)