В зависимости от компилятора следующий код:
int main()
{
srand( 0 );
if( rand() ) {
char buffer[600 * 1024] = {};
printf( buffer );
} else {
char buffer[500 * 1024] = {};
printf( buffer );
}
return 0;
}
при запуске в системе с максимальным размером стека, равным 1 мегабайту, либо печатает пустую строку, либо вылетает с переполнением стека.
Разница в том, что разные компиляторы распределяют автоматическое хранилище по-разному.Большинство компиляторов выделяют хранилище для всех объектов при запуске функции , поэтому в приведенном выше коде они выделяют 600 + 400 = 1100 килобайт, что приводит к переполнению стека.Некоторые компиляторы умнее и видят, что эти два массива никогда не могут быть доступны одновременно, поэтому они повторно используют одну и ту же память и выделяют только 600 килобайт, и программа работает нормально.
Теперь в стандарте говорится (3.7 / 1) что длительность хранилища определяет минимальный потенциальный срок службы хранилища , а затем (3.7.2 / 1), что хранилище для этих объектов [с автоматической продолжительностью] длится до блока, в котором они созданысуществует .
Я не понимаю, как 3.7 / 1 и 3.7.2 / 1 должны применяться вместе.Один говорит, что длительность равна минимальный потенциал , а другой прямо говорит, что это продолжается до тех пор, пока существует блок .Похоже, согласно первому, обе стратегии распределения являются законными, но вторая требует, чтобы использовалась только стратегия повторного использования.
Как сосуществуют 3.7 / 1 и 3.7.2 / 1?Законно ли выделять больше памяти, чем требуется программе в худшем случае (первая стратегия)?