Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не создаётся массив с размером по величине, const переменной 
V
    Опции темы
KaraKum
  Дата 1.6.2008, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Доброе время суток.
Такой код:
Код

const unsigned int count = Function();
unsigned int lettersArray[count];

Выдаются ошибки: (все ко второй строке)
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
PM MAIL WWW   Вверх
maxim1000
Дата 1.6.2008, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



размер такого массива должен быть не просто константой, а константой, известной на момент компиляции
если он становится известен только в процессе работы программы, придётся использовать динамическую работу с памятью


--------------------
qqq
PM WWW   Вверх
ifndef
Дата 1.6.2008, 09:52 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 25.5.2008
Где: Россия, Москва

Репутация: нет
Всего: нет



Подкреплю ответ maxim1000 примером..  smile 
Можно сделать так:

Код

unsigned int numel;
...
numel = Function(...);

// Выделение памяти под массив
unsigned int *arr = new unsigned int [numel];
........
// работа с массивом
........
//Освобождение памяти
delete [] arr;


PM MAIL ICQ   Вверх
KaraKum
Дата 1.6.2008, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Компилируется.
Большое спасибо  smile .

Вопрос помечен как решённый.
PM MAIL WWW   Вверх
Mayk
Дата 2.6.2008, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Зававно, что в C99 это работает. 


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Alek86
Дата 2.6.2008, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



и должно работать

ограничение-то надуманное...
думаю просто в плюсах не стали убирать, так как есть vector

Добавлено через 28 секунд
практически то-же самое, что и delete[]


--------------------
user posted image    user posted image
PM MAIL   Вверх
maxim1000
Дата 2.6.2008, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(Alek86 @  2.6.2008,  10:17 Найти цитируемый пост)
ограничение-то надуманное...

ну как сказать...
в голову приходят 2 аргумента:

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

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

Это сообщение отредактировал(а) maxim1000 - 2.6.2008, 10:35


--------------------
qqq
PM WWW   Вверх
bsa
Дата 4.6.2008, 23:14 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Судя по сообщениям об ошибках, это компилятор от MS. На сколько мне известно, ее компиляторы не соответствуют стандарту c99.
PM   Вверх
MAKCim
Дата 5.6.2008, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(maxim1000 @  2.6.2008,  10:35 Найти цитируемый пост)
её адрес относительно кадра стека, используемого в функции становится непостоянным и не может быть "зашит" в ассемблерный код

может
GCC, к примеру, локальные переменные функции идентифицирует через RBP (EBP)
а формирование массива переменной длины идет через декрементацию RSP (ESP)
Код

int main() {
    int count, i;
    int array[count];
    for (i = 0; i < count; ++i) {
        int temp[i];
        count -= i;
    }
    return 0;
}

Код

main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $64, %rsp /* локальный стековый фрейм */
    movq    %rsp, %rax
    movq    %rax, -40(%rbp) /* сохранение текущей вершины стека (для раскрутки стека) */
    movl    -8(%rbp), %eax /* получение count */
    cltq /* расширение до 64-х разрядов (т. к int) */
    salq    $2, %rax /* count << 2 (размер массива array) */
/* выравнивание размера по 16-ти байтной границе */
    addq    $15, %rax
    addq    $15, %rax
    shrq    $4, %rax
    salq    $4, %rax
    subq    %rax, %rsp /* выделение памяти под массив array */
    movq    %rsp, -56(%rbp) /* запись адреса массива в переменную array */
    movq    -56(%rbp), %rax
/* выравнивание адреса нижней границы стека по 16-ти байтной границе */
    addq    $15, %rax
    shrq    $4, %rax
    salq    $4, %rax
    movq    %rax, -56(%rbp) /* запись выровненного адреса */
    movq    -56(%rbp), %rax
    movq    %rax, -24(%rbp) /* сохранение текущей вершины стека (для раскрутки стека) */
    movl    $0, -4(%rbp) /* i = 0 */
    jmp .L2
.L3:
    movq    %rsp, %rax
    movq    %rax, %rdx
    movl    -4(%rbp), %eax /* получение i */
    cltq /* расширение i */
/* выравнивание размера */
    salq    $2, %rax
    addq    $15, %rax
    addq    $15, %rax
    shrq    $4, %rax
    salq    $4, %rax
    subq    %rax, %rsp /* формирование массива temp */
    movq    %rsp, -48(%rbp) /* запись адреса массива в переменную temp */
/* выравнивание адреса */
    movq    -48(%rbp), %rax
    addq    $15, %rax
    shrq    $4, %rax
    salq    $4, %rax
    movq    %rax, -48(%rbp) /* запись выровненного адреса */
    movq    -48(%rbp), %rax
    movq    %rax, -16(%rbp) /* сохранение текущей вершины стека (для раскрутки стека) */
    movl    -4(%rbp), %eax /* получение i */
    subl    %eax, -8(%rbp) /* count -= i */
    movq    %rdx, %rsp /* раскрутка стека для temp */
    addl    $1, -4(%rbp) /* ++i */
.L2:
/* i < count? */
    movl    -4(%rbp), %eax
    cmpl    -8(%rbp), %eax
    jl  .L3 /* i < count */
    movl    $0, %eax
    movq    -40(%rbp), %rsp /* раскрутка стека для array */
    leave
    ret



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
maxim1000
Дата 5.6.2008, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(MAKCim @  5.6.2008,  09:27 Найти цитируемый пост)
может
GCC, к примеру, локальные переменные функции идентифицирует через RBP (EBP)
а формирование массива переменной длины идет через декрементацию RSP (ESP)

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

или я неправильно понял смысл?

Это сообщение отредактировал(а) maxim1000 - 5.6.2008, 15:12


--------------------
qqq
PM WWW   Вверх
bsa
Дата 5.6.2008, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



maxim1000, RSP - это указатель вершины стека. Его никто не резервирует smile
PM   Вверх
maxim1000
Дата 5.6.2008, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(bsa @  5.6.2008,  15:46 Найти цитируемый пост)
RSP - это указатель вершины стека. Его никто не резервирует

ну хорошо, использует smile
но основная мысль была про масштабируемость
ну никак я не пойму, как можно расширить этот подход для нескольких локальных массивов


--------------------
qqq
PM WWW   Вверх
MAKCim
Дата 5.6.2008, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(maxim1000 @  5.6.2008,  20:45 Найти цитируемый пост)
ну никак я не пойму, как можно расширить этот подход для нескольких локальных массивов 

смотри пример
там два локальных массива
с тем же успехом их может быть и 3, и 4, и 5, и...
здесь ключевой момент для понимания - это то, что переменная-массив является переменной-указателем, который содержит адрес массива в стеке

Это сообщение отредактировал(а) MAKCim - 5.6.2008, 20:53


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
maxim1000
Дата 6.6.2008, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



неее, я имел в виду, что если два локальных массива в самой функции, т.е.
Код

int main()
{
    int count;
    int array1[count];
    int array2[count];
    ...
}

здесь по-любому придётся вычислять адрес как минимум одного массива, а не вшивать сразу в ассемблерный код


--------------------
qqq
PM WWW   Вверх
MAKCim
Дата 6.6.2008, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(maxim1000 @  6.6.2008,  17:16 Найти цитируемый пост)
здесь по-любому придётся вычислять адрес как минимум одного массива, а не вшивать сразу в ассемблерный код 

а как ты предлагаешь "вшивать" адрес чего-либо в стеке?  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1093 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.