С++ не требует стека?

В первый раз, когда учитель познакомил меня с С++, одно из первых определений было посвящено "языкам на основе стека", таким как Java, C и С++.

Теперь я читал о этом в ответе, и я честно растерян.

С++ - это язык на основе стека, но не требует стека?

Ответ 1

Когда я слышу "язык на основе стека", я обычно думаю о языках, таких как FORTH, где все делается в стеке, т.е. нет переменных. Я догадываюсь, когда ваш учитель сказал Java, они имели в виду JVM, основанный на стеках.

Теперь в стандарте С++ нет абсолютно никакой концепции стека или кучи, только такие вещи, как автоматическое и динамическое хранилище. С++ указан в терминах более абстрактных идей, что позволяет теоретически работать над множеством различных реализаций и аппаратных средств. Конечно, оказывается, что эти идеи непосредственно касаются идеи стека, поэтому каждая реализация заканчивается тем, что она используется.

Ответ 2

Не- "основанный на стеке язык" - это не просто язык, для которого не требуется стек.

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

C и С++ могут быть или не быть основаны на стеках. Это полностью зависит от компилятора и целевого ОС/микропроцессора. Вы не можете предположить, что это так или нет. На практике, однако, он в значительной степени реализуется как на основе регистров.

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

Изменить: Nitpick, как было предложено пользователем mikera: язык байт-кода Java основан на стеках, но для его запуска в большинстве архитектур, основанных на регистре, вам понадобится что-то, что переводит язык байт-кода на основе стека в регистр на основе архитектуры. Эта работа может быть выполнена интерпретатором в JVM или с помощью JIT или не-JIT-байтового кода для родного компилятора.

Ответ 3

С++ (например, C, Java и большинство других блочно-структурированных языков) требует наличия "стека" в смысле какой-либо структуры данных, состоящей из последней очереди, для хранения записей активации для вызовов функций. То есть, функция может вызывать себя рекурсивно на какую-либо произвольную глубину, и, поскольку она делает это, параметры/локальные переменные для каждого вызова должны быть независимы от тех, которые были для предыдущих вызовов. По возвращении этих вызовов функций параметры/локальные переменные для каждого должны быть уничтожены.

Это, однако, не требует выполнения на CPU, который напрямую поддерживает стек в оборудовании. Полностью можно выполнить С++ (и другие языки с блочной структурой, как упоминалось выше) без прямой аппаратной поддержки стека.

Только, например, ранние Crays и (даже текущие) мэйнфреймы IBM не поддерживают стеки. Несмотря на это, они могут и поддерживают С++. По крайней мере, в большинстве случаев структура данных LIFO, используемая для записей активации, динамически распределяется и встраивается в связанный список. Поскольку каждая функция вызывается, ее активационная запись распределяется и добавляется в связанный список. Когда функция возвращается, эта активационная запись удаляется из списка и освобождается память.

Итак, если вы смотрите на вещи с несколько абстрактной точки зрения, думая о стеке как о сути основных операций, которые он предоставляет, то да, для С++ требуется стек. Если вы посмотрите на "стек" менее абстрактно и подумаете о чем-то вроде процессора с регистром указателя стека (или что-нибудь в этом порядке), то нет, С++ определенно не нуждается в стеке (и то же самое касается C, Java, и т.д.)

Ответ 4

Это семантика.

Подумайте о машине. Автомобиль описывается с точки зрения радио, скорости, сидений, CD-плеера, количества держателей чашек, цвета краски и т.д. В списке функций не говорится о том, откуда идет питание, чтобы запустить все это. Почти все автомобили используют газ, идущий к двигателю внутреннего сгорания, и двигатель поворачивает колеса и запускает генератор, чтобы заставить электричество управлять всеми аксессуарами. Двигатель не требуется, но у большинства автомобилей есть один.

Спецификация языка говорит о времени жизни данных. Он не говорит, как воплощается жизнь. Оказывается, 99% компиляторов С++ используют глобальные данные, стек и кучу, чтобы соответствовать требованиям к времени жизни данных, которые хочет получить язык.