![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
KaraKum |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 640 Регистрация: 3.12.2007 Репутация: 1 Всего: 1 |
Доброе время суток.
Такой код:
Выдаются ошибки: (все ко второй строке) error C2057: expected constant expression error C2466: cannot allocate an array of constant size 0 error C2133: 'lettersArray' : unknown size Если вызов функции заменить на значение, то ошибка пропадает, но нужно-то присвоить значение функции. Подскажите, пожалуйста, в чём проблема? Это сообщение отредактировал(а) KaraKum - 1.6.2008, 08:53 |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
размер такого массива должен быть не просто константой, а константой, известной на момент компиляции
если он становится известен только в процессе работы программы, придётся использовать динамическую работу с памятью -------------------- qqq |
|||
|
||||
ifndef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
Подкреплю ответ maxim1000 примером..
![]() Можно сделать так:
|
|||
|
||||
KaraKum |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 640 Регистрация: 3.12.2007 Репутация: 1 Всего: 1 |
Компилируется.
Большое спасибо ![]() Вопрос помечен как решённый. |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Зававно, что в C99 это работает.
-------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
Alek86 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
и должно работать
ограничение-то надуманное... думаю просто в плюсах не стали убирать, так как есть vector Добавлено через 28 секунд практически то-же самое, что и delete[] |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ну как сказать... в голову приходят 2 аргумента: 1. такие массивы могут быть использованы не только в каком-то блоке кода, но и, например, в структуре, там (по крайней мере мне) не видно простого способа сделать возможным инициализацию константой, неизвестной на момент компиляции (нужно учесть, что кто-то захочет сделать из структур массив, и нужно будет знать их размер), получается нужно разделять понятие такого массива на два: те, которые используются в структурах, и в блоках кода, а понятий в C++ и так немало 2. сужается простор для оптимизации: если у нас есть массив, а за ним какая-то локальная переменная, её адрес относительно кадра стека, используемого в функции становится непостоянным и не может быть "зашит" в ассемблерный код, если таких массивов несколько, придётся вычислять несколько адресов при входе в функцию (не или при первом использовании) Это сообщение отредактировал(а) maxim1000 - 2.6.2008, 10:35 -------------------- qqq |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Судя по сообщениям об ошибках, это компилятор от MS. На сколько мне известно, ее компиляторы не соответствуют стандарту c99.
|
|||
|
||||
MAKCim |
|
||||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
может GCC, к примеру, локальные переменные функции идентифицирует через RBP (EBP) а формирование массива переменной длины идет через декрементацию RSP (ESP)
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||||
|
|||||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ключевое слово - "массива" но ведь локальных массивов тоже может быть несколько, как и локальных переменных я сомневаюсь, что подобный метод может нормально масштабироваться (разве что резервируя под это всё новые и новые регистры) или я неправильно понял смысл? Это сообщение отредактировал(а) maxim1000 - 5.6.2008, 15:12 -------------------- qqq |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
maxim1000, RSP - это указатель вершины стека. Его никто не резервирует
![]() |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ну хорошо, использует ![]() но основная мысль была про масштабируемость ну никак я не пойму, как можно расширить этот подход для нескольких локальных массивов -------------------- qqq |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
смотри пример там два локальных массива с тем же успехом их может быть и 3, и 4, и 5, и... здесь ключевой момент для понимания - это то, что переменная-массив является переменной-указателем, который содержит адрес массива в стеке Это сообщение отредактировал(а) MAKCim - 5.6.2008, 20:53 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
неее, я имел в виду, что если два локальных массива в самой функции, т.е.
здесь по-любому придётся вычислять адрес как минимум одного массива, а не вшивать сразу в ассемблерный код -------------------- qqq |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
а как ты предлагаешь "вшивать" адрес чего-либо в стеке? ![]() -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
честно говоря, последний процессор, на котором я плотно работал с ассемблером, был не совсем стандартный, но смысл такой:
есть команда (приблизительно) rx0=[sp+<константа>], при чём константа должна быть известна на этапе сборки перевода в машинные коды даже если такой команды нет, то наверняка можно писать так: a=sp a+=<константа> b=[a] ключевой момент - должен быть такой адрес в стеке, относительно которого можно уже на этапе компиляции сказать адреса всех локальных переменных, тогда есть блок кода для определения адреса, количество команд которого не зависит от количества и типа локальных переменных, и, подозреваю, во всех современных процессорах сейчас это можно делать одной командой если у нас есть локальный массив переменной длины, то его начало относительно вершины стека компилятору уже неизвестно, да, можно выкрутиться, используя указатель на фрейм стека (не уверен в терминологии) - т.е. в стеке есть две точки, относительно одной из них начало массива имеет константный адрес, поэтому всё ещё хорошо однако, это - одноразовое решение: стоит нам добавить ещё один массив и смещение адреса начала второго массива относительно начала текущего фрейма будет зависеть от длины первого массива, а относительно вершины стека - от длины второго массива (ну ещё и от переменных, но их размеры известны), т.е. у нас уже не получается константности дальше для обеспечения быстрого доступа ко второму массиву и переменным между этими массивами уже придётся либо записывать его адрес в какой-то регистр, либо сохранять его в памяти первый вариант просто ужасен: регистры, если я не ошибаюсь, - дефицит, когда дело доходит до оптимизации второй вариант - добавление уровня косвенности - тоже не очень хорошо, особенно, если среди таких переменных окажется несколько важных ну а с ростом количества локальных массивов всё будет только ухудшаться - ведь начала их адресов нужно посчитать при входе в функцию ------- некоторое пояснение: я совсем не против такой возможности, более того - она, скорее всего, будет использована для замены динамической памяти, в которой затраты времени значительно больше всех вышеописанных, так что в этом смысле это - полжительное улучшение просто, как мне кажется, не очень хорошо делать их расширением старых добрых массивов с длиной, известной на этапе компиляии, - две вещи, которые беглым взглядом не всегда отличишь, имеют довольно-таки серьёзное отличие да, конечно, не так уж и часто встречаются функции с кучей локальных массивов, но у кого-то ведь встретятся, и будет он искать, почему при объявлении такого массива, критическая функция стала медленнее работать... фууух... длинненько вышло ![]() Это сообщение отредактировал(а) maxim1000 - 6.6.2008, 20:46 -------------------- qqq |
|||
|
||||
MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
maxim1000,
так, объясняю упрощенно ![]() есть код
для реализации массивов переменной длины a, b, c, d представляют собой не массивы, а переменные-указатели, содержащие адреса массивов в стеке i, j, k, q обычные целочисленные переменные итого у нас есть 8 локальных переменных в main() общим размером 4 * sizeof(void*) + 4 * sizeof(int) = 32 + 16 = 48 (на 64-х разрядной системе) для каждого блока кода (между { и }) в рамках функции, в котором определен массив переменной длины необходимо сохранять адрес текущей вершины стека (для раскрутки стека при выходе из блока) в данном примере блок один, поэтому необходима еще одна локальная переменная-указатель t 48 + 8 = 56
Добавлено через 12 минут и 58 секунд отличие только в том, что требуется дополнительное обращение к памяти за адресом массива а т. к стек в рамках функции используется крайне часто и много, то он с большой вероятностью будет находится в строках кэша т. е итоговое снижение производительности в среднем будет составлять 1 такт на одно обращение к массиву это очень мало -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ох, как знал, как знал
![]() сначала писал про два массива потом сделал приписку: может получиться такая ситуация:
так вот указателями станут не только a и b, но и, как это ни печально, i,j,k причём самое плохое, что усложнение доступа к i произошло из-за свойств других переменных - неочевидность удваивается -------------------- qqq |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
нет все локальные переменные размещаются в созданном при входе в функцию стековом фрейме ![]() т. е в данном случае a, b, n, m, i, j, k размещаются последовательно от [rsp] до [rbp] после декрементации rsp на 36 Это сообщение отредактировал(а) MAKCim - 6.6.2008, 22:19 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ннда... про перемещение места под локальные переменные внутренних блоков наверх как-то не подумал
тогда, похоже, остаётся один аргумент про различия в использовании ![]() (невозможность использовать в структурах, sizeof) так что всё равно мне кажется, что стоит это как-то по-другому было бы назвать, ввести какое-то визуальное отличие, а не одинаковую запись P.S. подумал про дополнительный такт при доступе к массивам: похоже и его не будет, ведь чаще всего к ним будут обращаться, итерируя указатели, а значит, дополнительная операция будет только при их инициализации, а значит, неважно... -------------------- qqq |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
maxim1000, с sizeof проблем тоже быть не должно. А вот в структурах использовать нельзя это точно.
|
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
ох... а тут как? ведь sizeof люди привыкли передавать, куда угодно например, в качестве аргументов шаблонов -------------------- qqq |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
можно пример, где ты это видел? возможно всё, но я как-то не припомню... |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 17 Всего: 110 |
не, я такого не видел, но учитывая, какие вещи делают на C++, сильно сомневаюсь, что такого ни у кого нету честно говоря, про sizeof сейчас в голову не приходит, но вот про сам тип такой конструкции вспомнилось, как шаблонами определяли длину массива так вот там использовалось, что массив из 10-ти int-ов имеет тип int[10], а не просто указатель, и этим пользовались при определении размера -------------------- qqq |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Да, но этим можно пользоваться при массивах константной длины. Конечно, руки всем не открутишь - найдутся те, которые обязательно сделают не так ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |