Re: Динамический массив на стэке
От: 24  
Дата: 07.09.11 12:06
Оценка: +1 -1 :)
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


В С стандарта 99-го года можно. В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):

template <typename T, int SIZE>
class Array {
public:
    T& operator[](int i) {return data[i];}

private:
    T data[SIZE];
}

void f( int n )
{
   Array<int, n> a;
}
Re: Динамический массив на стэке
От: panter_dsd Россия panter-dsd.narod.ru
Дата: 07.09.11 12:14
Оценка: +2 :)
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


А зачем, если есть std::vector?
С уважением.
Пантер.
Re[10]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 13:57
Оценка: +2 -1
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gegMOPO4, Вы писали:
PD>>>Последнее есть просто передача указателя на массив. Память под массив там не отводится.
MOP>>Да, именно так реализованы и локальные массивы нефиксированного размера. Это просто указатели.
PD>Массив — это блок памяти, и его кто-то должен все же выделить.

Да. Выше я написал, где и как этот блок выделяется и как его используют.

MOP>>Вообще-то, во многих языках есть полноценные многомерные массивы нефиксированного размера. Это возможно. Массив «под капотом» будет реализован не только указателем на начало блока данных массива, но и целым размером его строки (а размер элемента известен на момент компиляции).

PD>Вообще-то они есть в С/C++. Только не на стеке. Насчет того полноценныеони или нет — обсуждать не буду, пока не увижу определение , чем полноценные массивы отличаются от неполноценных
PD>А вот если приведешь пример языка, где они реализованы именно на стеке — тогда и будет о чем говорить.

У вас ведь вроде были сомнения в возможности реализации в языке двумерных массивов с неизвестным во время компиляции размером?

>>>>Но кому это нужно и стоит ли такое узкое применение реализации?

PD>>>Если разрешить динамические массивы — придется разрешить и динамические массивы из динамических массивов. Иначе архитектуре языка будет некоторое повреждение
MOP>>Никакого повреждения, если понимать логику языка. Ну вот сейчас параметр функции можно объявить как int a[][42], но нельзя как int a[42][] — такого же типа «повреждение».
PD>М-да. Может, все же разберешься сначала, почему нельзя...

Вообще-то, это у вас проблемы с пониманием синтаксиса и семантики C.

PD>>>И почему это узкое ? Еще какое широкое! Двумерные динамические матрицы встречаются сплошь и рядом (ну, правда, не в задачах создания сайтов . Хотя бы машинная графика.

MOP>>Узкое потому, что нельзя этот массив передать наружу из функции.
PD>Что узкое-то ? Двумерный против одномерного или динамический против фиксированной размерности ? Кстати, из функции вообще никакой массив передать наружу нельзя — еще не хватало передавать адрес локальной переменной после выхода из функции... static передать можно, но это дурной тон.

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

>>Нельзя иметь элементом структуры.

PD>Это еще почему ? Нигде в С нет ограничений на тип элемента массива.

Потому, что размер структуры в текущем C должен быть известен на этапе компиляции.

>>Нельзя иметь глобальную переменную.

PD>Несомненно. Хотел бы я посмотреть, как это можно в С присвоить значение размеру массива до начала выполнения программы.

Ну вот видите.

PD>Все, я закончил.


Если бы вы ещё больше думали и меньше троллили, я бы продолжил.
Re: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 07.09.11 15:51
Оценка: 5 (2)
Здравствуйте, 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.

Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.
With best regards
Pavel Dvorkin
Re: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 13:23
Оценка: 4 (1) -1
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


В C99 можно. И почти в любом компиляторе можно сделать вот так:

int *a = alloca( n * sizeof(int) );


Суть будет ровно та же самая, только синтаксис не столь приятный.
Re[2]: Динамический массив на стэке
От: Sni4ok  
Дата: 07.09.11 12:17
Оценка: +2
Здравствуйте, panter_dsd, Вы писали:

_>А зачем, если есть std::vector?


например затем, что выделение на стеке элементарная мгновенная операция, а выделение памяти под вектор очень дорогая конкурентная операция?
Re: Динамический массив на стэке
От: Анатолий Широков СССР  
Дата: 07.09.11 12:18
Оценка: 4 (1)
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

Можно в С99:
http://en.wikipedia.org/wiki/Variable-length_array

В С++ же используй alloca для схожих целей:


void foo(size_t size) {
   int* a = new (alloca(size*sizeof(int))) int[size];
   for(size_t i = 0; i < size; i++)
       a[i] = 0;
}
Re[3]: Динамический массив на стэке
От: Alexey F  
Дата: 07.09.11 13:35
Оценка: 2 (1)
Здравствуйте, sysenter, Вы писали:

24>>В С стандарта 99-го года можно. В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):

S>C++x11 вроде, как должен поддерживать т.к. совместим с C99.
Нет, было предложение включить VLA (variable length arrays) в C++11, но данное предложение не прошло.
Re: Динамический массив на стэке
От: PM  
Дата: 08.09.11 05:50
Оценка: 1 (1)
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


Про функцию alloca() уже вспомнили, но почему-то никто не упомянул что проблем она создает больше, чем удобств (см., например, Бойтесь alloca
Автор: rm822
Дата: 26.03.07
)

Потенциальная возможность исчерпания стека и, как следствие, необходимость контролировать размер выделяемой памяти, потому что в Visual C++

A stack overflow exception is generated if the space cannot be allocated. The stack overflow exception is not a C++ exception; it is a structured exception.


На других платформах поведение вероятнее всего тоже будет неопределенным.

И что писать так?

void f(int n)
{
   int* a;
   if ( n <= SMALL_MAGIC_NUMBER )
   {
       a = alloca(n * sizeof(int)); 
   }
   else
   {
       a = new int[n]; // или выход с ошибкой
   }

   // работаем с a, но помним, что можем быть должны освободить память, т.е. никаких return и throw, только goto cleanup
   // я люблю старый добрый C, ведь на нем пишет сам Торвальдс!

cleanup:
   // нужно хорошо постараться, чтобы в С++ всегда попасть сюда при выходе из функции
   // добро пожаловать в ручное управление памятью!
   if ( n > SMALL_MAGIC_NUMBER )
   {
      delete a;
   }
}


Сравним с таким:
void f(int n)
{
   std::vector<int> a(n);

   // работаем с a, как обычным массивом, можно пользоваться throw и return, n может быть большим
}


На мой взгляд alloca — вредная функция. Если SMALL_MAGIC_NUMBER известен нам на этапе написания программы (из требований к исходной функции f), то можно использовать массив на стеке, иначе остается только std::vector или его аналоги с выделением памяти в куче.
Re: нет стэка кроме std::stack<T>
От: B0FEE664  
Дата: 08.09.11 15:51
Оценка: 1 (1)
Здравствуйте, Muxa, Вы писали:


Вообще-то (в стандарте C++11):

1.9.1
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract
machine
. This International Standard places no requirement on the structure of conforming implementations.



1.9.7 An instance of each object with automatic storage duration (3.7.3) is associated with each entry into its
block. Such an object exists and retains its last-stored value during the execution of the block and while the
block is suspended (by a call of a function or receipt of a signal).



15.2.3
The process of calling destructors for automatic objects constructed on the path from a try block to a
throw-expression is called “stack unwinding.”

Но это не значит, что переменные лежат в стеке.

Стека выполнения может и не быть
И каждый день — без права на ошибку...
Re[2]: Динамический массив на стэке
От: 24  
Дата: 07.09.11 12:09
Оценка: +1
Здравствуйте, 24, Вы писали:

24>В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):


С шаблонами так нельзя конечно, видимо я плохо выспался сегодня
Re[2]: Динамический массив на стэке
От: Sni4ok  
Дата: 07.09.11 12:18
Оценка: +1
Здравствуйте, Ops, Вы писали:

Ops>Вроде в GСС можно (нестандартное расширение). А вообще для этих целей есть alloca.


а alloca по вашему- стандартная функция?
Re[2]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 16:03
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.


Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.
Re[3]: Динамический массив на стэке
От: dilmah США  
Дата: 07.09.11 16:43
Оценка: +1
S>например затем, что выделение на стеке элементарная мгновенная операция

с чего это. Там каждой страницы нужно касаться
Re[4]: Динамический массив на стэке
От: Sni4ok  
Дата: 07.09.11 17:00
Оценка: :)
Здравствуйте, dilmah, Вы писали:


S>>например затем, что выделение на стеке элементарная мгновенная операция


D>с чего это. Там каждой страницы нужно касаться


ну мне казалось там просто изменение регистра- но не суть, всё равно по сравнению с malloc'ом это как стринги по сравнению с понталонами.
Re[8]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 09:00
Оценка: +1
Здравствуйте, gegMOPO4, Вы писали:

MOP>Специальный — будет. Как для каждого потока отдельный стек, так и область аллокации будет отдельная.


А delet'ать как из другого потока?
Re[4]: Динамический массив на стэке
От: Ops Россия  
Дата: 08.09.11 09:28
Оценка: +1
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, Ops, Вы писали:

Ops>>Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?

MOP>Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?


Я писал вот про это:

В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?

Не удовлетворяются они, выделение памяти в хипе в многопоточном приложении всегда дорогая операция. Выделение на стеке — дешевая.
Можно заранее выделять память и в потоке раздавать уже ее, но зачем, когда есть стек — та же самая предвыделенная память?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:30
Оценка: +1
Здравствуйте, Анатолий Широков, Вы писали:

АШ>В С++ же используй alloca для схожих целей:



АШ>
АШ>void foo(size_t size) {
АШ>   int* a = new (alloca(size*sizeof(int))) int[size];
АШ>   for(size_t i = 0; i < size; i++)
АШ>       a[i] = 0;
АШ>}
АШ>



IMHO, в С++ alloca лучше не использовать. Он плохо взаимодействует с inline-подстановками, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[11]: Динамический массив на стэке
От: B0FEE664  
Дата: 08.09.11 15:51
Оценка: +1
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, B0FEE664, Вы писали:

BFE>>Здравствуйте, Ops, Вы писали:
Ops>>>Зачем отдельную область аллокации, когда уже есть стек?
BFE>>Как известно
Автор: B0FEE664
Дата: 07.09.11
, стандарт я ещё не прочитал. Вы уверены, что стек упоминается в стандарте С++ и обязателен при реализации ?


MOP>Да, в стандарте C++11 он упоминается. 23.6.5.

Это совсем другой стек
И каждый день — без права на ошибку...
Re[8]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 08.09.11 23:30
Оценка: +1
Здравствуйте, gegMOPO4, Вы писали:

Pzz>>У большинства, кстати, указателя стека именно что нету. В качестве такового используется регистр общего назначения.


MOP>Даже если это РОН, то РОН выделенный, зарезервированный для этой цели (как и указатель команд). Ведь у процессора есть и команда вызова подпрограммы, и прерывания.


Будете смеяться, специальной команды вызова подпрограммы может и не быть. А для обработки прерываний на архитектурах без встроенного аппаратного стека может использоваться механизм переключения банков регистров.
Динамический массив на стэке
От: Muxa  
Дата: 07.09.11 11:56
Оценка:
Я сейчас глупость спрошу:
Почему нельзя сделать вот так?

void f( int n )
{
   int a[n];
}
Re: Динамический массив на стэке
От: Ops Россия  
Дата: 07.09.11 12:07
Оценка:
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?

M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


Вроде в GСС можно (нестандартное расширение). А вообще для этих целей есть alloca.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Динамический массив на стэке
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 07.09.11 12:12
Оценка:
Здравствуйте, 24, Вы писали:

24>Здравствуйте, 24, Вы писали:


24>>В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):


24>С шаблонами так нельзя конечно, видимо я плохо выспался сегодня

если облажался, можно удалить топик как ошибочный.
Sic luceat lux!
Re[4]: Динамический массив на стэке
От: Ops Россия  
Дата: 07.09.11 12:13
Оценка:
Здравствуйте, Kernan, Вы писали:

24>>С шаблонами так нельзя конечно, видимо я плохо выспался сегодня

K>если облажался, можно удалить топик как ошибочный.
Пока на него не ответили...
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Динамический массив на стэке
От: Ops Россия  
Дата: 07.09.11 12:24
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>Здравствуйте, Ops, Вы писали:


Ops>>Вроде в GСС можно (нестандартное расширение). А вообще для этих целей есть alloca.


S>а alloca по вашему- стандартная функция?


Нет, но поддерживается большинством компиляторов, в отличие от.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[4]: Динамический массив на стэке
От: Sni4ok  
Дата: 07.09.11 12:33
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Нет, но поддерживается большинством компиляторов, в отличие от.


так то да, а я предпочитаю заведомо большой буфер на стеке выделить- и с ним работать, накладных расходов — никаких, и всё честно
Re[2]: Динамический массив на стэке
От: sysenter  
Дата: 07.09.11 13:20
Оценка:
Здравствуйте, 24, Вы писали:

24>В С стандарта 99-го года можно. В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):


C++x11 вроде, как должен поддерживать т.к. совместим с C99.
Re[3]: Динамический массив на стэке
От: sysenter  
Дата: 07.09.11 13:26
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>например затем, что выделение на стеке элементарная мгновенная операция, а выделение памяти под вектор очень дорогая конкурентная операция?


Не такая уж и дорогая. Понятное дело, что дороже чем выделение в стеке, но runtime библиотека имеет свой кеш памяти, чтобы каждый раз у системы не запрашивать, не фрагментировать и не требовать для пары байт целую страницу (4096). Обратно системе runtime библиотека так же возвращает не всю освободивщуюся память.
Re: Динамический массив на стэке
От: x-code  
Дата: 07.09.11 16:39
Оценка:
Здравствуйте, Muxa, Вы писали:

M>Я сейчас глупость спрошу:

M>Почему нельзя сделать вот так?
M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


А можно я глупый вопрос продолжу?
А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать. На асме обычно пишут что-то типа "push eax" и все. А при выходе из фунцкии стек все равно восстанавливается.
Re[2]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 16:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>За все компляторы и платформы, конечно, не скажу, ограничусь x86. Но, думаю, в других системах то же.


PD>Когда все массивы статические, суммарный объем данных , размещаемых на стеке, при входе в функцию известен до ее выполнения. Поэтому компилятор просто строит код, изменяющий значение регистра стека на суммарный объем. Кстати, по крайней мере VC++ делает это именно при входе в функцию, а не при входе в блок, как вроде бы требовалось. Поэтому в пределах функции значение регистра стека не меняется (конечно, оно изменится, если внутри этой функции войти в другую, но тогда в другой будет то же самое, а выйдем — вернемся в исходное состояние вызываюшей функции). Поэтому адреса всех стековых переменных (и массивов, и скаляров) можно определить в момент входа в функцию и они в ней меняться не будут. В x86 для этого используется базирование по регистру EBP.

Именно! Именно ebp!

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.

Указатель на текущий фрейм стека сохраняется в ebp. Но выделение массива на стеке его не затрагивает, это выделение делается изменением регистра esp. Ну то есть адресация всех локальных переменных внутри функции никак не изменяется, она не зависит от esp, так как базой служит ebp, а на этот регистр стековые массивы никак не влияют. Никаких там падений скорости нет, код доступа к локальным переменным даже не меняется.
Re[2]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 17:00
Оценка:
Здравствуйте, x-code, Вы писали:

XC>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.

А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.
Re[3]: Динамический массив на стэке
От: dilmah США  
Дата: 07.09.11 17:25
Оценка:
XC>>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.
WM>А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.

тем не менее в Си неполноценная поддержака этого.
Скажем, ты не можешь вызвать функцию с переменным и *динамически* определяемым кол-вом аргументов
Re: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:31
Оценка:
Здравствуйте, Muxa, Вы писали:
M>Почему нельзя сделать вот так?

Как выше уже отметили, в C99 можно. Почему же нельзя в C++ — тому две причины.

1. Для int, вроде, никаких проблем, как и для других POD, а вот насчёт классов с деструктором не уверен. Особенно учитывая исключения.
2. Если в функции есть массив переменного размера, то будет, как заметил Pavel Dvorkin, небольшой оверхед (даже если его не использовать).

В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:33
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.

А всё это лишние команды, лишние такты.
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:35
Оценка:
Здравствуйте, watch-maker, Вы писали:
WM>Указатель на текущий фрейм стека сохраняется в ebp.

А ведь можно было бы и не сохранять. Вот на этом и оверхед.
Re[4]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 17:45
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, watch-maker, Вы писали:

WM>>Указатель на текущий фрейм стека сохраняется в ebp.

MOP>А ведь можно было бы и не сохранять. Вот на этом и оверхед.

Ну детский сад прямо. Этот оверхед — две инструкции. И во-первых, фреймы стека и так много где используются, независимо от поддержки VLA. Во вторых, компилятору ничего не мешает не включать фреймы, если в конкретной функции нет VLA. В-третьих, это всё равно в тысячи раз быстрее, чем выделение массива в куче.
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 18:01
Оценка:
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, watch-maker, Вы писали:
WM>>>Указатель на текущий фрейм стека сохраняется в ebp.
MOP>>А ведь можно было бы и не сохранять. Вот на этом и оверхед.
WM>Ну детский сад прямо. Этот оверхед — две инструкции. И во-первых, фреймы стека и так много где используются, независимо от поддержки VLA. Во вторых, компилятору ничего не мешает не включать фреймы, если в конкретной функции нет VLA. В-третьих, это всё равно в тысячи раз быстрее, чем выделение массива в куче.

Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор. Притом в момент запроса (всё равно инициализация массива съест больше), а не при входе в функцию (даже если массив не понадобился).

И если практически того же самого легко добиться самому, то зачем менять язык? Он и так сложный.
Re[4]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 18:31
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, Pzz, Вы писали:

Pzz>>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.

MOP>А всё это лишние команды, лишние такты.


Указатель на стек на входе все равно удобно иметь под рукой, чтобы добираться до параметров. Большинство компиляторов все равно генерируют enter/leave (или эквиавалент), независимо от наличия alloca() или массивов переменной длинны
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 18:46
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, Pzz, Вы писали:
Pzz>>>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.
MOP>>А всё это лишние команды, лишние такты.
Pzz>Указатель на стек на входе все равно удобно иметь под рукой, чтобы добираться до параметров. Большинство компиляторов все равно генерируют enter/leave (или эквиавалент), независимо от наличия alloca() или массивов переменной длинны

Указатель на стек всё равно есть в подавляющем большинстве современных платформ (у которых вообще есть стек). Обращаться по константному смещению от вершины стека одинаково удобно, независимо от количества локальных переменных. От дорогих enter/leave компиляторы избавляются при включенной оптимизации (особенно от конкретно enter/leave).
Re[2]: Динамический массив на стэке
От: Ops Россия  
Дата: 07.09.11 18:59
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?


Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 19:14
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?

Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?
Re[2]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 07.09.11 19:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В x86 для этого используется базирование по регистру EBP.


Может использоваться базирование по EBP, для отладки; а так: omit frame pointer и вперед.

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.


Никто не требует размещать переменные в стеке в порядке их объявления и никто не запрещает размещать динамические массивы в стеке после всех остальных переменных.
Re[3]: Динамический массив на стэке
От: x-code  
Дата: 07.09.11 19:51
Оценка:
Здравствуйте, watch-maker, Вы писали:

XC>>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.

WM>А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.

Я говорю о прямом ручном размещении объкетов в стеке, через push, и извлечении через pop. Да, это небезопасно, можно случайно повредить стековые переменные или адрес возврата, но ведь на то он и Си чтобы быть небезопасным, да и чтобы повредить переменные есть гораздо более простые способы
Re[6]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 22:46
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Указатель на стек всё равно есть в подавляющем большинстве современных платформ (у которых вообще есть стек). Обращаться по константному смещению от вершины стека одинаково удобно, независимо от количества локальных переменных. От дорогих enter/leave компиляторы избавляются при включенной оптимизации (особенно от конкретно enter/leave).


У большинства, кстати, указателя стека именно что нету. В качестве такового используется регистр общего назначения.

Компилятор избавляется от возни со стеком, если функция достаточно "простая" для этого. Наличие или отсутствие alloca или эквиавалента — лишь еще один критерий простоты.
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:44
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

MP>Никто не требует размещать переменные в стеке в порядке их объявления


Я об этом и не говорил.

>и никто не запрещает размещать динамические массивы в стеке после всех остальных переменных.


После — это как ?


{
  int x;
  int y[n];
  {
    int z;
    int t[m];


Кто тут после кого ?
With best regards
Pavel Dvorkin
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:52
Оценка:
Здравствуйте, watch-maker, Вы писали:

PD>>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.

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

Отлично. Раскажи, как ты будешь получать доступ к локальным переменым через EBP, если при входе в функцию размещается два динамических массива. Они же тоже локальные переменные, к ним тоже надо добраться
With best regards
Pavel Dvorkin
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:54
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности


Чуть подробнее, пожалуйста. На входе куда : в функцию ? в блок ?
With best regards
Pavel Dvorkin
Re[4]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 01:34
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>
PD>{
PD>  int x;
PD>  int y[n];
PD>  {
PD>    int z;
PD>    int t[m];
PD>


PD>Кто тут после кого ?


push    ebp  
mov     ebp,esp
sub     esp,8
...
mov     [ebp-4],eax     ;   x
mov     [ebp-8],eax     ;   z
...
sub     esp,N           ;   N=4*n
...
sub     esp,M           ;   M=4*m
...
mov     [ebp-4],eax     ;   по прежнему x
mov     [ebp-8],eax     ;   по прежнему z
                        ;   т. о. имеем синтаксический оверхед только для самих динамических массивов
...


Проверял без фанатизма, но первый взгляд показал, что именно так — вполне логично как по мне — поступает MSVC++ при использовании alloca (выделяет переменные известного размера до переменного участка и использует ebp даже при указании omit frame pointers). В общем никакой сложности и оверхеда, ну разве что frame pointer теперь не можем опустить.
Re[5]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 03:03
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

MP>Здравствуйте, Pavel Dvorkin, Вы писали:


MP> ; т. о. имеем синтаксический оверхед только для самих динамических массивов


Не синтаксический. Обращаться к элементам массива как будешь ? Через ebp ? При том, что в стеке сейчас несколько массивов бог знает какой длины, к тому же при следующем вызове длины могут оказаться иными.


MP>Проверял без фанатизма, но первый взгляд показал, что именно так — вполне логично как по мне — поступает MSVC++ при использовании alloca (выделяет переменные известного размера до переменного участка и использует ebp даже при указании omit frame pointers). В общем никакой сложности и оверхеда, ну разве что frame pointer теперь не можем опустить.


А вот насчет использования ebp пожалуйста, подробнее. Я что-то не пойму, как можно обращаться к элементам нескольких подряд расположенных массивов переменной длины через одну базу, не зная их размеров.
With best regards
Pavel Dvorkin
Re[2]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 06:39
Оценка:
Здравствуйте, PM, Вы писали:
PM>На мой взгляд alloca — вредная функция. Если SMALL_MAGIC_NUMBER известен нам на этапе написания программы (из требований к исходной функции f), то можно использовать массив на стеке, иначе остается только std::vector или его аналоги с выделением памяти в куче.

Более того, с std::vector мы можем использовать пользовательский аллокатор, который при малом объёме будет выделять память в специальной заранее распределённой области (быстро, просто изменив пару указателей). Постойте-ка, да ведь стандартный аллокатор именно так и работает!
Re[7]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 06:51
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Указатель на стек всё равно есть в подавляющем большинстве современных платформ (у которых вообще есть стек). Обращаться по константному смещению от вершины стека одинаково удобно, независимо от количества локальных переменных. От дорогих enter/leave компиляторы избавляются при включенной оптимизации (особенно от конкретно enter/leave).
Pzz>У большинства, кстати, указателя стека именно что нету. В качестве такового используется регистр общего назначения.

Даже если это РОН, то РОН выделенный, зарезервированный для этой цели (как и указатель команд). Ведь у процессора есть и команда вызова подпрограммы, и прерывания.
Re[4]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 06:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, MescalitoPeyot, Вы писали:
>>и никто не запрещает размещать динамические массивы в стеке после всех остальных переменных.
PD>После — это как ?
PD>
PD>{
PD>  int x;
PD>  int y[n];
PD>  {
PD>    int z;
PD>    int t[m];
PD>

PD>Кто тут после кого ?

Хм, думал, вы это понимаете. Компилятор резервирует на стеке место для следующих переменных постоянного размера:
int x;
int * y;
int z;
int * t;

А потом вызывает y = (int *)alloca(sizeof(int)*n) в начале функции и t = (int *)alloca(sizeof(int)*m) в начале блока. Для циклов придётся ещё и сохранять/восстанавливать стек для каждой итерации.
Re[6]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 08:31
Оценка:
PD>А вот насчет использования ebp пожалуйста, подробнее. Я что-то не пойму, как можно обращаться к элементам нескольких подряд расположенных массивов переменной длины через одну базу, не зная их размеров.

Посмотрите как ведет себя MSVC++ при использовании alloca. Получает указатель для динамического блока и юзает непосредственно его. К остальным локальным переменным вне зависимости от места их объявления обращается при этом как и раньше, через ebp и постоянное смещение. Вот абсоютно также и будет делать в случае с динамическими массивами. К тому же на первый (и единственный, что очень часто бывает) динамический массивы вообще через esp обращаться можно. Короче, возьмите компилятор и посмотрите что он сделает с вашим фрагментом (только замените динамический массив на alloca или MSVC++ на GCC и volatil'ов каких-нибудь порасставляйте, чтоб никого не убило), все вопросы сразу отпадут.
Ваша ошибка, по-видимому, в том, что вы считаете что компилятор выделяет переменные в порядке объявления и в начале каждого блока. Однако это не так даже для дебажной сборки.
Re[6]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 08:33
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор.


Я так понимаю этот аллокатор, который в 2-3 раза, еще и с потоками дружить не будет в отличии от.
Re[2]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 08:43
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>1. Для int, вроде, никаких проблем, как и для других POD, а вот насчёт классов с деструктором не уверен. Особенно учитывая исключения.


Не уверен, что это проблема (вопрос нуждается в дополнительном исследовании), но в крайнем случае можно просто запретить динамические массивы с не-POD типами, точно также как это сделано для другой C-шной фичи, функций с переменным числом аргументов.

MOP>2. Если в функции есть массив переменного размера, то будет, как заметил Pavel Dvorkin, небольшой оверхед (даже если его не использовать).


Весь оверхед — обязательное занятие регистра ebp под frame pointer в таких функциях. В функциях где используются динамические массивы и (или) alloca он будет, где нет — нет будет. Напомню, к слову, что по-дефолту MSVC++ компиляет код в релизе с frame pointers.
Re[7]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 08:46
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:
MP>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор.
MP>Я так понимаю этот аллокатор, который в 2-3 раза, еще и с потоками дружить не будет в отличии от.

Специальный — будет. Как для каждого потока отдельный стек, так и область аллокации будет отдельная.
Re[9]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 09:12
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:
MP>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Специальный — будет. Как для каждого потока отдельный стек, так и область аллокации будет отдельная.
MP>А delet'ать как из другого потока?

Мы о замене alloca, или уже о чём-то другом?
Re[10]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 09:37
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Мы о замене alloca, или уже о чём-то другом?


Просто ни alloca, ни динамический массив ни на что такое не претендуют, а аллокатор — это аллокатор, назвался аллокатором, будь добр, соответствуй. Что можно замутить свой пул на поток, а потом постоянно следить чтоб объект из него никуда случайно не передать и громко чесать репу при портировании на какой-нибудь без-TLS-ный Андроид, в этом я ничуть не сомневаюсь.
Re[5]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 09:39
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Хм, думал, вы это понимаете. Компилятор резервирует на стеке место для следующих переменных постоянного размера:

MOP>int x;
MOP>int * y;
MOP>int z;
MOP>int * t;

Тогда получится, что для массивов фиксированной длины имя массива есть константа, а для массивов переменной длины — нет. Боюсь, что это приведет к серьезной ревизии очень много в языке.

Кстати, сказав a, скажите и b. Как насчет многомерных массивов с переменной длиной ?
With best regards
Pavel Dvorkin
Re[7]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 09:44
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

PD>>А вот насчет использования ebp пожалуйста, подробнее. Я что-то не пойму, как можно обращаться к элементам нескольких подряд расположенных массивов переменной длины через одну базу, не зная их размеров.


MP>Посмотрите как ведет себя MSVC++ при использовании alloca. Получает указатель для динамического блока и юзает непосредственно его. К остальным локальным переменным вне зависимости от места их объявления обращается при этом как и раньше, через ebp и постоянное смещение. Вот абсоютно также и будет делать в случае с динамическими массивами. К тому же на первый (и единственный, что очень часто бывает) динамический массивы вообще через esp обращаться можно.


Именно на первый. На остальные нет, а при использовании _alloca будешь делать сам и помнить, где что.

MP>Ваша ошибка, по-видимому, в том, что вы считаете что компилятор выделяет переменные в порядке объявления и в начале каждого блока.


Я уже ответил раньше — не считаю. И никакой ошибки тут нет. Размещать переменные можно в любом порядке, независимо от описания, но если их размеры известны до входа в функцию, то для каждой переменной или члена массива известно его смещение от ebp и его можно записать в команде явно . Если неизвестны — нельзя (разве что для первого). От порядка размещения тут ничего не зависит.

Кстати, а как насчет многомерных динамических массивов ?
With best regards
Pavel Dvorkin
Re[8]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 10:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD> Если неизвестны — нельзя (разве что для первого). От порядка размещения тут ничего не зависит.


Правильно это записывается так: "Можно для всех кроме второго и последующих динамических массивов, если они вообще есть". И в чем проблема? Духу плюсов ("не платить за то что не используешь") не противоречит, зато сохраняется совместимость с голыми сями.

PD>Кстати, а как насчет многомерных динамических массивов ?


А они разрешены? В любом случае проблемы проблемы не вижу.
Re[6]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 10:21
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Хм, думал, вы это понимаете. Компилятор резервирует на стеке место для следующих переменных постоянного размера:
MOP>>int x;
MOP>>int * y;
MOP>>int z;
MOP>>int * t;
PD>Тогда получится, что для массивов фиксированной длины имя массива есть константа, а для массивов переменной длины — нет. Боюсь, что это приведет к серьезной ревизии очень много в языке.

Массивы фиксированной длины и массивы переменной длины, которые появились в C99, — совсем разные вещи. Кстати, массивы как локальные переменные и массивы без указания размера как параметры функции тоже разные вещи. К серьёзной ревизии это не привело, ведь раньше такой сущности, как массив переменного размера, не было.

PD>Кстати, сказав a, скажите и b. Как насчет многомерных массивов с переменной длиной ?


Почему бы и нет? Но кому это нужно и стоит ли такое узкое применение реализации?
Re[8]: Динамический массив на стэке
От: Ops Россия  
Дата: 08.09.11 10:25
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, MescalitoPeyot, Вы писали:

MP>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор.
MP>>Я так понимаю этот аллокатор, который в 2-3 раза, еще и с потоками дружить не будет в отличии от.

MOP>Специальный — будет. Как для каждого потока отдельный стек, так и область аллокации будет отдельная.


Зачем отдельную область аллокации, когда уже есть стек?
Оккама на вас нет, он бы вам поотрезал сущности.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[11]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 10:26
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:
MP>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Мы о замене alloca, или уже о чём-то другом?
MP>Просто ни alloca, ни динамический массив ни на что такое не претендуют, а аллокатор — это аллокатор, назвался аллокатором, будь добр, соответствуй.

С чего бы это? Специализированный аллокатор или контейнер для замены массивов неконстантного размера (для тех, кого не устраивают стандартные) претендует только на замену массивов неконстантного размера.

MP>то можно замутить свой пул на поток, а потом постоянно следить чтоб объект из него никуда случайно не передать и громко чесать репу при портировании на какой-нибудь без-TLS-ный Андроид, в этом я ничуть не сомневаюсь.


А куда-нибудь случайно передать указатель на локальную переменную не боитесь?
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 10:36
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, Ops, Вы писали:
Ops>>>Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?
MOP>>Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?
Ops>Я писал вот про это:
Ops>

Ops>В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?

Ops>Не удовлетворяются они, выделение памяти в хипе в многопоточном приложении всегда дорогая операция. Выделение на стеке — дешевая.
Ops>Можно заранее выделять память и в потоке раздавать уже ее, но зачем, когда есть стек — та же самая предвыделенная память?

Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.
Re[9]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 10:44
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, MescalitoPeyot, Вы писали:
MP>>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>>Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор.
MP>>>Я так понимаю этот аллокатор, который в 2-3 раза, еще и с потоками дружить не будет в отличии от.
MOP>>Специальный — будет. Как для каждого потока отдельный стек, так и область аллокации будет отдельная.
Ops>Зачем отдельную область аллокации, когда уже есть стек?
Ops>Оккама на вас нет, он бы вам поотрезал сущности.

Вот Оккам и режет. Зачем вводить специальный случай аллокации на стеке переменного размера (а к этому нужно обеспечить и вызовы деструкторов в нужном месте, и восстановление стека в циклах, и с инлайном не ошибиться) для реализации очень частного случая массивов переменного размера (которые и вовне функции не передашь, и размер не изменишь), когда уже существующими универсальными средствами можно легко реализовать как такие специальные ограниченны массивы, так и более универсальные?
Re[9]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 10:47
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

MP>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>> Если неизвестны — нельзя (разве что для первого). От порядка размещения тут ничего не зависит.


MP>Правильно это записывается так: "Можно для всех кроме второго и последующих динамических массивов, если они вообще есть". И в чем проблема?


В том, что придется менять и усложнять алгоритм доступа к второму и другим массивам. Не предлагаешь же ты запретить более одного динамического массива ?

>Духу плюсов ("не платить за то что не используешь") не противоречит, зато сохраняется совместимость с голыми сями.


Духами я не занимаюсь , а вот то, что от этой идеи отказались давным-давно — факт.

PD>>Кстати, а как насчет многомерных динамических массивов ?


MP>А они разрешены?


Если ты предлагаешь разрешить

int a[n];

то будь добр разрешить и

int b[n][m];


>В любом случае проблемы проблемы не вижу.


А доступ как будет осуществляться ?
With best regards
Pavel Dvorkin
Re[7]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 11:00
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Массивы фиксированной длины и массивы переменной длины, которые появились в C99, — совсем разные вещи. Кстати, массивы как локальные переменные и массивы без указания размера как параметры функции тоже разные вещи.


Последнее есть просто передача указателя на массив. Память под массив там не отводится.

PD>>Кстати, сказав a, скажите и b. Как насчет многомерных массивов с переменной длиной ?


MOP>Почему бы и нет?


А если да, то расскажи, как будешь доступ к ним осуществлять. Массив указателей создавать будешь при входе в функцию и заполнять его ?

>Но кому это нужно и стоит ли такое узкое применение реализации?


Если разрешить динамические массивы — придется разрешить и динамические массивы из динамических массивов. Иначе архитектуре языка будет некоторое повреждение

И почему это узкое ? Еще какое широкое! Двумерные динамические матрицы встречаются сплошь и рядом (ну, правда, не в задачах создания сайтов . Хотя бы машинная графика.
With best regards
Pavel Dvorkin
Re[8]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 11:44
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Массивы фиксированной длины и массивы переменной длины, которые появились в C99, — совсем разные вещи. Кстати, массивы как локальные переменные и массивы без указания размера как параметры функции тоже разные вещи.
PD>Последнее есть просто передача указателя на массив. Память под массив там не отводится.

Да, именно так реализованы и локальные массивы нефиксированного размера. Это просто указатели.

PD>>>Кстати, сказав a, скажите и b. Как насчет многомерных массивов с переменной длиной ?

MOP>>Почему бы и нет?
PD>А если да, то расскажи, как будешь доступ к ним осуществлять. Массив указателей создавать будешь при входе в функцию и заполнять его ?

Вообще-то, во многих языках есть полноценные многомерные массивы нефиксированного размера. Это возможно. Массив «под капотом» будет реализован не только указателем на начало блока данных массива, но и целым размером его строки (а размер элемента известен на момент компиляции).

>>Но кому это нужно и стоит ли такое узкое применение реализации?

PD>Если разрешить динамические массивы — придется разрешить и динамические массивы из динамических массивов. Иначе архитектуре языка будет некоторое повреждение

Никакого повреждения, если понимать логику языка. Ну вот сейчас параметр функции можно объявить как int a[][42], но нельзя как int a[42][] — такого же типа «повреждение».

PD>И почему это узкое ? Еще какое широкое! Двумерные динамические матрицы встречаются сплошь и рядом (ну, правда, не в задачах создания сайтов . Хотя бы машинная графика.


Узкое потому, что нельзя этот массив передать наружу из функции. Нельзя иметь элементом структуры. Нельзя иметь глобальную переменную.
Re[9]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 12:05
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

PD>>Последнее есть просто передача указателя на массив. Память под массив там не отводится.


MOP>Да, именно так реализованы и локальные массивы нефиксированного размера. Это просто указатели.


Массив — это блок памяти, и его кто-то должен все же выделить.

MOP>Вообще-то, во многих языках есть полноценные многомерные массивы нефиксированного размера. Это возможно. Массив «под капотом» будет реализован не только указателем на начало блока данных массива, но и целым размером его строки (а размер элемента известен на момент компиляции).


Вообще-то они есть в С/C++. Только не на стеке. Насчет того полноценныеони или нет — обсуждать не буду, пока не увижу определение , чем полноценные массивы отличаются от неполноценных
А вот если приведешь пример языка, где они реализованы именно на стеке — тогда и будет о чем говорить.

>>>Но кому это нужно и стоит ли такое узкое применение реализации?

PD>>Если разрешить динамические массивы — придется разрешить и динамические массивы из динамических массивов. Иначе архитектуре языка будет некоторое повреждение

MOP>Никакого повреждения, если понимать логику языка. Ну вот сейчас параметр функции можно объявить как int a[][42], но нельзя как int a[42][] — такого же типа «повреждение».


М-да. Может, все же разберешься сначала, почему нельзя...


PD>>И почему это узкое ? Еще какое широкое! Двумерные динамические матрицы встречаются сплошь и рядом (ну, правда, не в задачах создания сайтов . Хотя бы машинная графика.


MOP>Узкое потому, что нельзя этот массив передать наружу из функции.


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

>Нельзя иметь элементом структуры.


Это еще почему ? Нигде в С нет ограничений на тип элемента массива.

>Нельзя иметь глобальную переменную.


Несомненно. Хотел бы я посмотреть, как это можно в С присвоить значение размеру массива до начала выполнения программы.

Все, я закончил.
With best regards
Pavel Dvorkin
Re[6]: Динамический массив на стэке
От: Ops Россия  
Дата: 08.09.11 12:47
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.


Слава яйцам, что не Вы решаете, что нужно в стандарте, иначе бы мы не только лямбд не дождались, но и шаблонов бы не увидели.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[7]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 12:56
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.
Ops>Слава яйцам, что не Вы решаете, что нужно в стандарте, иначе бы мы не только лямбд не дождались, но и шаблонов бы не увидели.

Укажете пункт стандарта, в котором описаны локальные массивы нефиксированной длины?
Re[8]: Динамический массив на стэке
От: Ops Россия  
Дата: 08.09.11 13:02
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, Ops, Вы писали:

Ops>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.
Ops>>Слава яйцам, что не Вы решаете, что нужно в стандарте, иначе бы мы не только лямбд не дождались, но и шаблонов бы не увидели.

MOP>Укажете пункт стандарта, в котором описаны локальные массивы нефиксированной длины?


Ну и я об этом. Если бы Вы решали — там бы и пунктов про шаблоны не было.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:28
Оценка:
Здравствуйте, 24, Вы писали:

24>В С стандарта 99-го года можно.


+1

24>В С++ впринципе можно шаблонами выкрутиться, как-то так (пишу в браузере):

24>
24>template <typename T, int SIZE>
24>class Array {
24>public:
24>    T& operator[](int i) {return data[i];}

24>private:
24>    T data[SIZE];
24>}

24>void f( int n )
24>{
24>   Array<int, n> a;
24>}
24>

А так, вроде бы нельзя...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:29
Оценка:
Здравствуйте, panter_dsd, Вы писали:
M>>Почему нельзя сделать вот так?

M>>
M>>void f( int n )
M>>{
M>>   int a[n];
M>>}
M>>


_>А зачем, если есть std::vector?


Например, для эффективности...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 13:32
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, Ops, Вы писали:
Ops>>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>>Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.
Ops>>>Слава яйцам, что не Вы решаете, что нужно в стандарте, иначе бы мы не только лямбд не дождались, но и шаблонов бы не увидели.
MOP>>Укажете пункт стандарта, в котором описаны локальные массивы нефиксированной длины?
Ops>Ну и я об этом. Если бы Вы решали — там бы и пунктов про шаблоны не было.

Я вам излагаю причины, по которым этого в стандарте нет, а вы о чём?

Или не приписав собеседнику какую-то очевидно бредовую мысль (я ведь ничего не говорил о своём отношении к шаблонам и массивам переменного размера) и не развенчав её, день пропал зря?
Re[2]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:32
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.


Странно как-то, в С перекрывает, занчит, а в С++ нет?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:39
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Мы о замене alloca, или уже о чём-то другом?


Ты, вроде как о std::vector с каким-то хитрым аллокатором...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Динамический массив на стэке
От: Erop Россия  
Дата: 08.09.11 13:42
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Тогда получится, что для массивов фиксированной длины имя массива есть константа, а для массивов переменной длины — нет.

почему это? И то и то раз проинициализированное, уже никогда не меняется. При этом, так как переменная автоматическая, то константа времени исполнения, а не компиляции...

PD>Боюсь, что это приведет к серьезной ревизии очень много в языке.

Вряд ли.

PD>Кстати, сказав a, скажите и b. Как насчет многомерных массивов с переменной длиной ?

А как в С99 сделано?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 13:44
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.
E>Странно как-то, в С перекрывает, занчит, а в С++ нет?..

В C нет классов, шаблонов и перегрузки операторов — выгода больше (а проблем меньше).
Re: CAutoBuffer
От: Erop Россия  
Дата: 08.09.11 13:49
Оценка:
Здравствуйте, Muxa, Вы писали:

M>Почему нельзя сделать вот так?


M>
M>void f( int n )
M>{
M>   int a[n];
M>}
M>


Про С99 уже сказали, а про С++ не нужно так делать, потому, что есть более удачная техника работы с буферами на стеке
Автор: Erop
Дата: 06.09.10
!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Динамический массив на стэке
От: B0FEE664  
Дата: 08.09.11 14:05
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Зачем отдельную область аллокации, когда уже есть стек?


Как известно
Автор: B0FEE664
Дата: 07.09.11
, стандарт я ещё не прочитал. Вы уверены, что стек упоминается в стандарте С++ и обязателен при реализации ?
И каждый день — без права на ошибку...
Re[10]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 14:27
Оценка:
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, Ops, Вы писали:
Ops>>Зачем отдельную область аллокации, когда уже есть стек?
BFE>Как известно
Автор: B0FEE664
Дата: 07.09.11
, стандарт я ещё не прочитал. Вы уверены, что стек упоминается в стандарте С++ и обязателен при реализации ?


Да, в стандарте C++11 он упоминается. 23.6.5.

Вот в стандарте C99 упоминания не нахожу.
Re[10]: Динамический массив на стэке
От: Ops Россия  
Дата: 08.09.11 14:58
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, Ops, Вы писали:

Ops>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>Здравствуйте, Ops, Вы писали:
Ops>>>>Здравствуйте, gegMOPO4, Вы писали:
MOP>>>>>Затем, что это мы можем сделать прямо сейчас, существующими универсальными средствами языка, а вот выделять переменный размер на стеке — уже понадобиться вводить новую базовую фичу, менять грамматику языка. И очень специализированную фичу. Вот не было бы в языке классов, шаблонов, инлайна и перегрузки операторов — тогда это имело бы смысл. Но это не был бы C++.
Ops>>>>Слава яйцам, что не Вы решаете, что нужно в стандарте, иначе бы мы не только лямбд не дождались, но и шаблонов бы не увидели.
MOP>>>Укажете пункт стандарта, в котором описаны локальные массивы нефиксированной длины?
Ops>>Ну и я об этом. Если бы Вы решали — там бы и пунктов про шаблоны не было.

MOP>Я вам излагаю причины, по которым этого в стандарте нет, а вы о чём?


Вы излагаете то, что Вам кажется, а не причины. Я не вижу серьезных проблем с добавлением подобной фичи в язык. В GCC же сделали, не затронув всего языка, и ни классы, ни шаблоны этому не помешали. От Вас — ни одного аргумента против, только утверждения, что лучше все делать "существующими универсальными средствами языка".

MOP>Или не приписав собеседнику какую-то очевидно бредовую мысль (я ведь ничего не говорил о своём отношении к шаблонам и массивам переменного размера) и не развенчав её, день пропал зря?


Дальше спорить не хочу, т.к. бесполезно.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[11]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 16:49
Оценка:
Здравствуйте, Ops, Вы писали:
MOP>>>>Укажете пункт стандарта, в котором описаны локальные массивы нефиксированной длины?
Ops>>>Ну и я об этом. Если бы Вы решали — там бы и пунктов про шаблоны не было.
MOP>>Я вам излагаю причины, по которым этого в стандарте нет, а вы о чём?
Ops>Вы излагаете то, что Вам кажется, а не причины. Я не вижу серьезных проблем с добавлением подобной фичи в язык. В GCC же сделали, не затронув всего языка, и ни классы, ни шаблоны этому не помешали. От Вас — ни одного аргумента против, только утверждения, что лучше все делать "существующими универсальными средствами языка".

Если вас не устраивает этот ниодин аргумент, то вам, безусловно, нетрудно будет привести настоящие причины, по которым в языке C++ до сих пор нет массивов с неконстантным количеством элементов.

Ops>Дальше спорить не хочу, т.к. бесполезно.


Вот это правильно, и не нужно было спорить о вещах, в которых не разбираетесь.
Re[4]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 18:30
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?


С такой точки зрения нам и переменное число аргументов не нужно: я и на std::stack<boost::any> printf набросать смогу. Кроме того, не видел ни одного плюсового компилятора, который не умеет компилить сишный код, так что у всех кто собирается поддерживать новейший прям только вчера принятый С99 эта фича будет работать из коробки.
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 08.09.11 19:07
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:
MP>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?
MP>С такой точки зрения нам и переменное число аргументов не нужно: я и на std::stack<boost::any> printf набросать смогу.

printf уже был в C, и широко использовался. Пришлось поддерживать. А так, конечно, эллипсис (в том виде, как пришёл из C) — зло. Но с этим ничего не поделаешь.

MP>Кроме того, не видел ни одного плюсового компилятора, который не умеет компилить сишный код, так что у всех кто собирается поддерживать новейший прям только вчера принятый С99 эта фича будет работать из коробки.


C++ разрабатывался (почти) совместимым с тогдашним C, чтобы можно было использовать уже наработанный код и плавно переходить к использованию достоинств C++. Для C99 такой проблемы нет — те, кто почему-то используют C99 (а не ограниченное подмножество C++), в курсе, какие фичи несовместимы с C++, да и кода такого мало.

Компиляторы C++ не обязательно поддерживают C99. И необязательно смешивание C++ и C99 безопасно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.