LINUX.ORG.RU

Динамически выделяемые локальные массивы в c++


0

0
Возник такой вопрос: динамически выделяемые локальные массивы (т. е. место под которые выделяется в стеке) является частью стандарта c или гнутым расширением? К примеру, нижеприведённый код gcc-4.1 нормально компилирует (и он нормально работает), а мелкомягкий компилятор (из msvs) - нет:

int n=10;
double a[n];

Проверялось дебаггером - генерируемый код на второй строке действительно пододвигает указатель стека, выделяя таким образом в нём место для массива.
★★★
Ответ на: комментарий от devinull
> попробуй скаомпилить с -ansi и gcc тебе все объяснит.

Компилирует молча, вообще ничего не говорит. Причём в режиме любых стандартов.

slav ★★★
() автор топика
Ответ на: комментарий от kitov
> Как заставить msvc это скомпилировать ?

Вот у меня вопрос как раз возник потому что msvs это не компилирует. То ли это расширение стандарта, то ли это msvs стандарты не полностью поддерживает...

slav ★★★
() автор топика
C99 - является. Раньше, АФАИК, не являлось. С++ - не является.
Legioner ★★★★★
()
Ответ на: комментарий от kitov
n должна быть константой времени компиляции, конкретно твой пример фиксится так:

const int n=10; 
double a[n];

 
aton
()
Ответ на: комментарий от Begemoth
> в C++ надо использовать std::vector, а не всякие пережитки С

...за исключением случаев, когда "пережитки" гораздо быстрее ;)

tailgunner ★★★★★
()
Ответ на: комментарий от Begemoth
Бездумное использование std::vector может весьма негативное сказаться на производительности, т.к. скорость выделения памяти на стеке в разы быстрее.  
aton
()
Ответ на: комментарий от aton
Это вы сами придумали или прочитали где? Хотя, не сомневаюсь, у вас такое может иметь место. А под стек память выделять не надо? Откуда же она берётся?
sergio_nsk
()
Ответ на: комментарий от tailgunner
В каком месте они "гораздо быстрее" ? тесты есть? vector этот тот же массив Си, только завернутый внутрь класса. Если так хочется с ним работать как с double *, то возьми адрес нулевого элемента.
Reset ★★★★★
()
Ответ на: комментарий от Reset
> В каком месте они "гораздо быстрее" ?

Если моя память мне ни с кем не изменяет, при создании вектора производится вызов operator new (в случае использования дефолтного аллокатора). При создании массива auto производится арифметическая операция с указателем стека. Вот это и называется "гораздо быстрее".

> тесты есть?

Зачем? В любом случае, спрашивай OP.

> vector этот тот же массив Си, только завернутый внутрь класса.

Да ты что? Нет, правда? :)

> Если так хочется с ним работать как с double *, то возьми адрес нулевого элемента.

И зачем в таком случае использовать vector?

Еще раз: использовать вектор или auto-массив - зависит от обстоятельств.

tailgunner ★★★★★
()
Ответ на: комментарий от YesSSS
ну так и calloc() тоже инициализирует. дело не в этом - мне было интересно узнать отличие для того, чтобы понять насколько в new добавлено больше накладных расходов по сравнению с тем же malloc()/calloc().

P.S. собственно касательно отличия в скорости - выделение массива в стеке это просто изменения SP и если память для стека выделена то page fault'ов не будет (что очень быстро); в случае malloc()/calloc() я так понимаю добавляются дорогие jump'ы на ф-ции и идут syscall'ы в случае необходимости (двигают brk-адрес) в случае если в пуле недостаточно памяти ну и page-fault'ы тоже возможны тк cow используется. P.P.S. хм, вообще интересно где может быть критична скорость выделения/освобождения памяти - может с дизайном не всё в порядке?...

Mr_Nobody
()
Ответ на: комментарий от Mr_Nobody
new вызывает конструкторы для классов (а те вызыватют конструкторы своих частей и т.д.) => jump-ов и просто действий может быть много.

Если не ошибаюсь аллокация обычно делается через анонимный mmap и расширяется как и степ при pf-ах. Правда там обычно захватывают больше одной страницы а потом хитро распределяют.

Т.е. в большинстве случаев imho при alloc-е нет pf-ов, есть просто вызов стандартной библиотеки в том-же процессе. И разница не катастрофична(нету лишних syscall/pf).

YesSSS ★★★
()
Ответ на: комментарий от YesSSS
вот интересно стало как определяется падение производительности в процентном соотношении кол-во syscall'ов/кол-во page fault'ов?

мне почему то кажется что большое кол-во page fault'ов хуже чем большое кол-во сисколов (хотя понятно что сисколы косвенно бьют и по другим вешам - кэшу например)...

Mr_Nobody
()
Ответ на: комментарий от Mr_Nobody
> вот интересно стало как определяется падение производительности в процентном соотношении кол-во syscall'ов/кол-во page fault'ов?

не знаю, я про это не говорил.

> мне почему то кажется что большое кол-во page fault'ов хуже чем большое кол-во сисколов (хотя понятно что сисколы косвенно бьют и по другим вешам - кэшу например)...

imho примерно одинаково, главное переключение в ядро есть и возможно обращение к диску. Тут уж не до кэша. =)

YesSSS ★★★
()
Ответ на: комментарий от YesSSS
ну если не ошибаюсь page fault не всегда означает доступ к диску (может просто SIGSEGV) - так что не факт что 50/50

испоганивание кеша и reschedule при выходе из сискола тоже счастья не добавляют (хотя по сравнению с доступом к диску это сущая ерунда)

Mr_Nobody
()
Ответ на: комментарий от tailgunner
... за исключением случаев когда нужна переносимость между компиляторами

локальные массивы переменной длины - есть в С99, но являются гнутым расширением для С++

Begemoth ★★★★★
()
Ответ на: комментарий от tailgunner
может быть - писал по памяти, но смысл ИМХО передан верно.
Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.