-Wframe-larger-than
Предупреждение генерируется -Wframe-larger-than
. man gcc
из GCC 7 говорит:
Предупреждать, если размер функционального кадра больше, чем длина байта. Вычисления, сделанные для определения размера кадра стека, являются приблизительными и не являются консервативными.
фактические требования могут быть несколько выше, чем len, даже если вы не получили предупреждение. Кроме того, любое пространство, выделенное через "alloca", массивы переменной длины,
или связанные конструкции не включены компилятором при определении того, следует ли выдавать предупреждение.
Минимальный пример
int main(void) {
char s[1024];
return 0;
}
и
$ gcc -std=c99 -O0 -Wframe-larger-than=1 a.c
a.c: In function ‘main’:
a.c:4:1: warning: the frame size of 1040 bytes is larger than 1 bytes [-Wframe-larger-than=]
}
^
$ gcc -std=c99 -O0 -Wframe-larger-than=2048 a.c
# No warning.
Почему это существует
Операционные системы должны ограничивать размер стека, иначе он будет расти, пока не достигнет кучи / mmap
s, и все будет непредсказуемо сломаться.
Linux отправляет сигнал, если программа пытается выйти за пределы этого максимального размера стека.
-Wframe-larger-than=
- это способ предотвратить переполнение стека, сохраняя локальные переменные функции (которые помещаются в стек) небольшими.
Однако нет гарантии времени компиляции, поскольку проблема, вероятно, возникает при вызове рекурсивных функций, и все сводится к тому, сколько раз она повторяется.
Решение состоит в том, чтобы выделить память с malloc
вместо использования больших массивов в качестве локальных переменных. Это заканчивается использованием mmap
памяти.
Ключевое различие между стеком и malloc
памятью состоит в том, что стек должен быть смежным, что просто приводит к большой эффективности упаковки памяти, тогда как malloc
требует сложной эвристики. Смотри также: