Здравствуйте, 24, Вы писали:
24>Здравствуйте, 24, Вы писали:
24>>В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):
24>С шаблонами так нельзя конечно, видимо я плохо выспался сегодня
если облажался, можно удалить топик как ошибочный.
Здравствуйте, Kernan, Вы писали:
24>>С шаблонами так нельзя конечно, видимо я плохо выспался сегодня K>если облажался, можно удалить топик как ошибочный.
Пока на него не ответили...
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, Ops, Вы писали:
Ops>>Вроде в GСС можно (нестандартное расширение). А вообще для этих целей есть alloca.
S>а alloca по вашему- стандартная функция?
Нет, но поддерживается большинством компиляторов, в отличие от.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Sni4ok, Вы писали:
S>например затем, что выделение на стеке элементарная мгновенная операция, а выделение памяти под вектор очень дорогая конкурентная операция?
Не такая уж и дорогая. Понятное дело, что дороже чем выделение в стеке, но runtime библиотека имеет свой кеш памяти, чтобы каждый раз у системы не запрашивать, не фрагментировать и не требовать для пары байт целую страницу (4096). Обратно системе runtime библиотека так же возвращает не всю освободивщуюся память.
Здравствуйте, sysenter, Вы писали:
24>>В С стандарта 99-го года можно. В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере): S>C++x11 вроде, как должен поддерживать т.к. совместим с C99.
Нет, было предложение включить VLA (variable length arrays) в C++11, но данное предложение не прошло.
Здравствуйте, Muxa, Вы писали:
M>Я сейчас глупость спрошу: M>Почему нельзя сделать вот так?
M>
M>void f( int n )
M>{
M> int a[n];
M>}
M>
Причина идеологическая.
В ранних языках (Алгол-60, PL/1) это было можно
begin
integer n;
input(n);
begin
integer array a[1:n];
...
Впоследствии от этой идеи отказались.
За все компляторы и платформы, конечно, не скажу, ограничусь x86. Но, думаю, в других системах то же.
Когда все массивы статические, суммарный объем данных , размещаемых на стеке, при входе в функцию известен до ее выполнения. Поэтому компилятор просто строит код, изменяющий значение регистра стека на суммарный объем. Кстати, по крайней мере VC++ делает это именно при входе в функцию, а не при входе в блок, как вроде бы требовалось. Поэтому в пределах функции значение регистра стека не меняется (конечно, оно изменится, если внутри этой функции войти в другую, но тогда в другой будет то же самое, а выйдем — вернемся в исходное состояние вызываюшей функции). Поэтому адреса всех стековых переменных (и массивов, и скаляров) можно определить в момент входа в функцию и они в ней меняться не будут. В x86 для этого используется базирование по регистру EBP.
Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.
Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.
Здравствуйте, Muxa, Вы писали:
M>Я сейчас глупость спрошу: M>Почему нельзя сделать вот так? M>
M>void f( int n )
M>{
M> int a[n];
M>}
M>
А можно я глупый вопрос продолжу?
А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать. На асме обычно пишут что-то типа "push eax" и все. А при выходе из фунцкии стек все равно восстанавливается.