Подтвердить что ты не робот

Являются "слишком большими" объектами с продолжительным временем хранения undefined?

A недавний вопрос относительно SO "Почему выделение большого элемента в стеке не выполняется в этом конкретном случае?" и ряд других вопросов, касающихся "больших массивов в стеке" или "ограничений размера стека", заставил меня искать связанные ограничения, задокументированные в стандарте.

Я знаю, что стандарт C не указывает "стек", и поэтому он не определяет никаких ограничений для такого стека. Но я задавался вопросом, к какому SIZE_X в void foo() { char anArray[SIZE_X]; ... } стандарт гарантирует работу программы, и что произошло, если программа превысила этот SIZE_X.

Я нашел следующее определение, но я не уверен, что это определение на самом деле является гарантией для определенного поддерживаемого размера объектов с автоматической продолжительностью хранения (см. этот онлайн-проект C11):

5.2.4.1 Ограничения перевода

(1) Реализация должна иметь возможность переводить и выполнять по крайней мере одна программа, которая содержит по крайней мере один экземпляр каждого из следующие пределы:

...

65535 байт в объекте (только в размещенной среде)

Означает ли это, что реализация должна поддерживать значение до 65535 для SIZE_X в функции типа void foo() { char anArray[SIZE_X]; ... } и что любое значение, превышающее 65535 для SIZE_X, является undefined поведением?

Для кучи вызов malloc, возвращающий NULL, позволяет мне контролировать попытку запроса "слишком больших объектов". Но как я могу контролировать поведение программы, если она "запрашивает слишком большой объект с автоматической продолжительностью хранения", особенно если такой максимальный размер не был документирован, например. в некотором limits.h? Таким образом, можно написать переносимую функцию типа checkLimits(), поддерживающую "барьер ввода", например:

int main() {
   if(! checkLimits()) {
      printf("program execution for sure not supported in this environment.");     
      return 1;
   } else {
      printf("might work. wish you good luck!"); 
   }
   ...
}
4b9b3361

Ответ 1

Технически для реализации требуется только перевести и выполнить одну программу с 65,535-байтовым объектом (и другими перечисленными выше), чтобы соответствовать стандарту. Это может потерпеть неудачу на всех остальных.

Чтобы знать, что работают более крупные программы, вы должны опираться на детали вашей конкретной реализации. Большинство реализаций обеспечивают больше пространства стека, чем 64 KiB, хотя это может быть недокументировано. Для настройки допустимого пространства стека могут быть компоновщики.

Например, для компоновщика ld в текущем macOS по умолчанию используется 8 MiB, а переключатель -stack_size может использоваться для установки более или менее (для основного потока).

Я бы сказал, что, поскольку стандарт C говорит, что экологические ограничения, такие как пространство стека, могут ограничивать реализацию, ничего, кроме того факта, что одна конкретная программа-образец должна работать, технически undefined.