Форум программистов, компьютерный форум CyberForum.ru

хитрая константа не даёт создать обычный массив - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.88
Bers
Заблокирован
25.11.2011, 18:47     хитрая константа не даёт создать обычный массив #1
Почему я не могу создать обычный массив, указав константу в качестве количества элементов?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int n=10;
const int N(n); //N вроде как константа 
                     //действительно получает значение 10
 
 
int A[N]; //error C2057: требуется константное выражение
             //error C2466: невозможно выделить память 
             //для массива постоянного нулевого размера
 
int main()
{
   int b= N; //b получает корректное значение 10
   const int c=N; //с получает корректное значение
   return 0;
};
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.11.2011, 18:51     хитрая константа не даёт создать обычный массив #2
Bers, Ибо нех такое творить.

C++
1
2
3
int n = some_long_func();
const int N = n;
int array[N];
И отлично что так не создается.
prazuber
108 / 108 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 18:56     хитрая константа не даёт создать обычный массив #3
Потому что n не const. В новом стандарте, если не ошибаюсь, лечится constexpr.
Bers
Заблокирован
25.11.2011, 18:56  [ТС]     хитрая константа не даёт создать обычный массив #4
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Потому что n не const
При чем здесь вообще n?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
25.11.2011, 18:59     хитрая константа не даёт создать обычный массив #5
Bers, ну логично должно быть
C++
1
2
3
const int n=10;
const int N(n); //N вроде как константа 
                     //действительно получает значение 1
prazuber
108 / 108 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 18:59     хитрая константа не даёт создать обычный массив #6
Хорошо, выражусь по-другому. Так как n не const, то ее значение неизвестно на этапе компиляции, пускай даже вы присваиваете константу.
Bers
Заблокирован
25.11.2011, 19:01  [ТС]     хитрая константа не даёт создать обычный массив #7
Цитата Сообщение от PraZuBeR Посмотреть сообщение
Хорошо, выражусь по-другому. Так как n не const, то ее значение неизвестно на этапе компиляции, пускай даже вы присваиваете константу.
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?

Если бы это было нельзя - компилятор ругался бы в принципе на саму попытку таким образом инициализировать константу.

Но он не ругается. Убери массив, и работай с константой, как обычно.

Очень многие константы создаются в рантайме, и почему то на них компилятор никак не буксует.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
25.11.2011, 19:01     хитрая константа не даёт создать обычный массив #8
Цитата Сообщение от Bers Посмотреть сообщение
При чем здесь вообще n?
Да при том!
C++
1
2
int n=6;
const int N=n; //как видите это не эквивалентно const int N=6
prazuber
108 / 108 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:03     хитрая константа не даёт создать обычный массив #9
Цитата Сообщение от Bers Посмотреть сообщение
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?

Если бы это было нельзя - компилятор ругался бы в принципе на саму попытку таким образом инициализировать константу.

Но он не ругается. Убери массив, и работай с константой, как обычно.

Очень многие константы создаются в рантайме, и почему то на них компилятор никак не буксует.
Тут ничего противозаконного. А вот создание массива с помощью такой константы - вот это противозаконно.
Bers
Заблокирован
25.11.2011, 19:03  [ТС]     хитрая константа не даёт создать обычный массив #10
Цитата Сообщение от go Посмотреть сообщение
Да при том!
Что значит не эквивалентно?

Константа инициализируется один раз при создании. Все. Дальше есть только значение константы.
Никого не волнует, откуда она его получила.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
25.11.2011, 19:03     хитрая константа не даёт создать обычный массив #11
C++
1
2
const int n=6;
const int N=n;
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
25.11.2011, 19:03     хитрая константа не даёт создать обычный массив #12
Цитата Сообщение от Bers Посмотреть сообщение
Ну и что? Константа инициализируется значением, не известным на этапе компиляции. Что здесь такого противозаконного?
значение константы может зависеть только от других констант
rtfm же
Bers
Заблокирован
25.11.2011, 19:04  [ТС]     хитрая константа не даёт создать обычный массив #13
Цитата Сообщение от alex_x_x Посмотреть сообщение
значение константы может зависеть только от других констант
почему тогда при попытке инициализировать константу не_константой компилятор молчит?

Он ругается только при попытке создать с её помощью массив. А как он вообще определяет, что она палёная? И почему тогда вообще позволяет такие константы делать?
Сыроежка
Заблокирован
25.11.2011, 19:16     хитрая константа не даёт создать обычный массив #14
Цитата Сообщение от Bers Посмотреть сообщение
почему тогда при попытке инициализировать константу не_константой компилятор молчит?

Он ругается только при попытке создать с её помощью массив. А как он вообще определяет, что она палёная? И почему тогда вообще позволяет такие константы делать?
Размер массива компилятор должен знать на этапе компиляции, а ваша константа инициализируется на этапе выполнения. То есть для вашей константы компилятор генерирует некоторый код, который будет пересылать значение из переменной в константу.

Я вам приведу похожий пример. Допустим есть единица компиляции, в которой объявлено

C++
1
const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
Компилятор не будет компилировать второй модуль, не смотря на то, что N объявлена как константа, так как компилятору неисзвестно ее значение на этапе компиляции второго модуля.
prazuber
108 / 108 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:21     хитрая константа не даёт создать обычный массив #15
Bers, есть два типа констант. Первые - те, что известны на этапе компиляции. Стандарт про это пишет так:
An integral constant-expression can involve only literals (2.13), enumerators, const variables or static
data members of integral or enumeration types initialized with constant expressions (8.5), non-type template
parameters of integral or enumeration types, and sizeof expressions.
Второй тип - все остальные. Ваше const int N является вторым типом, потому что не попадает в описание первого.
N инициализируется вначале работы программы, но уже в рантайме. Поэтому массив с помощью нее инициализировать нельзя. Зато можно написать такое
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int f()
{
    int a;
    cin>>a;
    return a;
}
 
const int N(f());
 
int main()
{
    cout<<N<<endl;
};
Upd. Ошибся немного с цитатами, поправил.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
25.11.2011, 19:23     хитрая константа не даёт создать обычный массив #16
Сыроежка, каждый компилятор по разному
C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
void main ()
{
   int size = 5 ;
   int arr [size] ;
 
printf ("Ok");
 
}
http://codepad.org/8W1Udtgr
prazuber
108 / 108 / 3
Регистрация: 29.04.2010
Сообщений: 240
25.11.2011, 19:24     хитрая константа не даёт создать обычный массив #17
go, это проблемы компилятора.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
25.11.2011, 19:25     хитрая константа не даёт создать обычный массив #18
go, то, что Вы показываете, называется variable-length array и никакого отношения к сабжу не имеет.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
25.11.2011, 19:32     хитрая константа не даёт создать обычный массив #19
Цитата Сообщение от PraZuBeR Посмотреть сообщение
go, это проблемы компилятора.
Нет, вот цитата
Массивы переменной длины

В С89 размерности массивов необходимо объявлять при помощи выражений из целых констант, причем размер массива фиксируется во время компиляции. В силу определенных обстоятельств, в С99 это правило было изменено. В С99 можно объявить массив, размерности которого определяются любыми допустимыми целыми выражениями, в том числе и такими, значения которых становятся известны только во время выполнения. Такой массив называется массивом переменной длины (variable-length array, VLA). Однако такими массивами могут быть только локальные массивы (то есть те, у которых область видимости — прототип или блок).

Не по теме:


Цитата Сообщение от fasked Посмотреть сообщение
то, что Вы показываете, называется variable-length array и никакого отношения к сабжу не имеет.
Не совсем так, нужно просто это понимать

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2011, 19:36     хитрая константа не даёт создать обычный массив
Еще ссылки по теме:

C++ Скопировать элементы Vector в обычный массив
Константа Пи в С++ C++
Можно ли создать проект не managed c++, а обычный c++, но с формами в VS2008? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Сыроежка
Заблокирован
25.11.2011, 19:36     хитрая константа не даёт создать обычный массив #20
Я написал пример, но никто меня не поправил! Видимо, кроме меня никто стандарт не знает!

То есть в этом примере допущена ошибка

C++
1
const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
По умолчанию константы имеют внутреннее связывание, поэтому в первом модуле также надо добавить спецификатор extern То есть должно быть


C++
1
extern const int N = 10;
а в другой единице компиляции объявлено

C++
1
2
3
extern const int N;
 
int a[N];
Yandex
Объявления
25.11.2011, 19:36     хитрая константа не даёт создать обычный массив
Ответ Создать тему
Опции темы

Текущее время: 17:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru