Чего неправильно?
От: Аноним  
Дата: 08.01.03 09:50
Оценка:
Привет!!!



class A
{
public:

static const int _size_is;

static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
//Почему???
};

const int A::_size_is=100;
int A::array[_size_is];
Re: Чего неправильно?
От: Stas Chistyakov Россия  
Дата: 08.01.03 09:58
Оценка:
Ну она константу требует на этапе компиляции, типа 1,2, ..... (В общем число конкретное)
Единственное, что можно сделать #define _SIZE_ = 4
static int array[_SIZE_]; , хотя это почти тоже самое, что и просто число
... << RSDN@Home 1.0 beta 4 >>
Re: Чего неправильно?
От: Кодт Россия  
Дата: 08.01.03 10:04
Оценка: 11 (2)
Здравствуйте, Аноним, Вы писали:

А>class A
А>{
А>public:

А>static const int _size_is; //(*)

А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>//Почему???
А>};

А>const int A::_size_is=100;
А>int A::array[_size_is];

Потому что (*) — это объявление некоторого константного объекта типа "int".

В C++ есть двойственность в отношении констант. С одной стороны, это — именованные литералы (т.е. значения, которые можно подставлять в выражения), а с другой стороны — это просто квалификатор доступа к переменным, наряду с volatile.

В объявлении класса константа — это всегда переменная, защищенная от модификации.

Чтобы обойти проблему, пиши так:
class A
{
  enum { _size_is = 123 };

  ...
};

В данном случае _size_is — это именованный литерал некоторого целочисленного типа.
Перекуём баги на фичи!
Re: Чего неправильно?
От: Bell Россия  
Дата: 08.01.03 10:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет!!!


А>

А>

А>class A
А>{
А>public:

А>static const int _size_is;
...

А>


Потому что выделенная строка есть объявление переменной _size_is, но никак не определение, а следовательно не является constant expression.
можно так:

class A
{
public:

static const int _size_is = 100;

static int array[_size_is];
};

int A::array[A::_size_is];


но не все компиляторы поддерживают этот синтаксис (MSVC6 например не поддерживает)
Любите книгу — источник знаний (с) М.Горький
Re: Чего неправильно?
От: Aquary Россия https://wmspanel.com/
Дата: 08.01.03 10:09
Оценка:
Здравствуйте, Аноним, Вы писали:

АА>static int array[_size_is];

А может, vector'ом...
https://wmspanel.com/nimble — Nimble Streamer media server for live and VOD HLS, RTMP, HTTP streaming
https://wmspanel.com/ — Control and reporting panel for Wowza and Nimble Streamer
http://scm-notes.blogspot.com/ — Блог об управлении конфигурацией
Re[2]: Чего неправильно?
От: Аноним  
Дата: 08.01.03 10:10
Оценка:
Здравствуйте, Кодт, Вы писали:

Избыточное цитирование удалено. -- ПК.

К>Чтобы обойти проблему, пиши так:

К>
К>class A
К>{
К>  enum { _size_is = 123 };
К>  ...
К>};
К>

К>В данном случае _size_is — это именованный литерал некоторого целочисленного типа.

Ясно, спасибо!!! Ща сделаем...
Re[2]: Чего неправильно?
От: IgorK Россия  
Дата: 08.01.03 10:12
Оценка:
Здравствуйте, Stas Chistyakov, Вы писали:

SC>Ну она константу требует на этапе компиляции, типа 1,2, ..... (В общем число конкретное)

SC>Единственное, что можно сделать #define _SIZE_ = 4
SC>static int array[_SIZE_]; , хотя это почти тоже самое, что и просто число

Ну почему же... Можно и без #define:

/*
    Можно так
*/
class A
{
public:
    static const int _size_is = 100;
    static int array[_size_is]; 
};

const int A::_size_is;
int A::array[_size_is];

/*
    А можно и вот так
*/
class A
{
public:
    enum { _size_is = 100 };
    static int array[_size_is]; 
};

int A::array[_size_is];

/*
    И еще так
*/
class A
{
public:
    static const int _size_is;
    static int array[]; 
};

const int A::_size_is = 100;
int A::array[_size_is];
Re: Чего неправильно?
От: Dima_Ch Беларусь  
Дата: 08.01.03 10:13
Оценка:
Здравствуйте, Аноним, Вы писали:



А>Привет!!!


А>

А>

А>class A
А>{
А>public:

А>static const int _size_is;

А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>// Размер массива должен быть известен - вот почему

  // а статическая переменная к этому не обязывает
  //  ;)
А>};

А>const int A::_size_is=100;
А>int A::array[_size_is];

А>



const int _size_is =100;

class A
{
public:
     int array[_size_is];
};


дешево и сердито
если же для каждого экземпляра нужен свой размер массива, то такой подход не катит — ну и не надо
проще добавить в конструктор параметр размер массива, и выделять его линамически либо руками , либа используя встроенный класс , например std::vector
Re: Чего неправильно?
От: Дмитрий Наумов  
Дата: 08.01.03 11:42
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Привет!!!


А>

А>

А>class A
А>{
А>public:

А>static const int _size_is;

А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>//Почему???
А>};

ИМХО, так как массив тоже static, то время жизни и момент инициализации у них одинаковые. Гарантии что константа будет проинициализированна раньше чем массив нет.

А>const int A::_size_is=100;
А>int A::array[_size_is];

А>
... << RSDN@Home 1.0 beta 4 >>
Re[2]: Чего неправильно?
От: Кодт Россия  
Дата: 08.01.03 11:52
Оценка: 3 (1)
Здравствуйте, Дмитрий Наумов, Вы писали:

ДН>ИМХО, так как массив тоже static, то время жизни и момент инициализации у них одинаковые. Гарантии что константа будет проинициализированна раньше чем массив нет.


Это только ИМХО.

Статические объекты в одной единице компиляции всегда инициализируются в порядке взаимных зависимостей.

Причина — в другом, а именно — в нелитеральности выражения (т.е. компилятор не может его вычислить сам).

Аналогично коду
static const size_t len = strlen("hello");
static char buf[len+1];

Сколько байт должен выделить компилятор? А .
Перекуём баги на фичи!
Re[3]: Чего неправильно?
От: DemAS http://demas.me
Дата: 09.01.03 05:54
Оценка:
Здравствуйте, Кодт, Вы писали:


К>Причина — в другом, а именно — в нелитеральности выражения (т.е. компилятор не может его вычислить сам).


Извини, что вмешиваюсь в беседу двух умных людей, но уж больно хочется узнать, что такое нелитеральность ?

К>Аналогично коду

К>
К>static const size_t len = strlen("hello");
К>static char buf[len+1];
К>

К>Сколько байт должен выделить компилятор? А .

Вот это:
#include <string.h>
#include <iostream.h>

void main()
{
    static const size_t len=strlen("hello");
    cout << len << endl;
}


Выдает 5. Поэтому я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни
... << Играет silent>>
Re[4]: Чего неправильно?
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 09.01.03 07:46
Оценка: 3 (1)
Здравствуйте, DemAS, Вы писали:

К>>Аналогично коду

К>>
К>>static const size_t len = strlen("hello");
К>>static char buf[len+1];
К>>

К>>Сколько байт должен выделить компилятор? А .

DAS> ... я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни


В данном случае компилятор должен знать, сколько памяти нужно для buf. Но strlen — библиотечная функция, а не ключевое слово языка C++. Компилятор не может знать, что делает эта функция и что она возвращает.
А еще можно написать свою функцию strlen...
... << RSDN@Home 1.0 beta 4 >>
Re[4]: Чего неправильно?
От: Кодт Россия  
Дата: 09.01.03 10:07
Оценка: 12 (2)
Здравствуйте, DemAS, Вы писали:

К>>Причина — в другом, а именно — в нелитеральности выражения (т.е. компилятор не может его вычислить сам).


DAS> Извини, что вмешиваюсь в беседу двух умных людей, но уж больно хочется узнать, что такое нелитеральность ?


Литеральность (лат+рус) — буквальность. Литерал — это (в вольной трактовке) значение, определенное своим написанием... Блин, да как же это сказать-то?!

Все числа ( 0, 1, 2.345, ... ) — это литералы.
Строки в явном написании ( "hello" ) — тоже литералы.
Элементы перечисления (enum) — замещают целые числа — тоже.
Имена функций и переменных — по сути, их адреса — тоже можно считать литералами.

Выражения, составленные только из литералов — по индукции — тоже литеральные.

Вызовы функций — не литеральны, так как компилятор не "знает", что делает данная функция (особенно, если она определена в другом модуле, и ее нельзя инлайнить),

А в отношении константных переменных (const some_type var = NNN) есть двойственность.
С одной стороны, компилятор "знает", что это значение никогда не изменится (будет равно NNN) — и может им пользоваться. Но, с другой стороны, это все-таки переменная, размещенная в памяти, со своим адресом (ее, кстати, можно изменить с помощью const_cast).
const double pi_1 = 3.14159265358; // литерал

/////////
extern const double pi_2; // константная переменная
...
const double pi_2 = 3.14159263658;

void hack_pi_2()
{
  const_cast<double>(pi_2) = exp(1); // вот такое заподло :)
}

/////////
const double pi_3 = atan(1)*4; // константная переменная;
                               // значение будет присвоено незадолго до входа в main()


К>>Аналогично коду

К>>static const size_t len = strlen("hello");
К>>static char buf[len+1];

К>>Сколько байт должен выделить компилятор? А .

DAS> Вот это:

DAS>
DAS>#include <string.h>
DAS>#include <iostream.h>

DAS>void main()
DAS>{
DAS>    static const size_t len=strlen("hello");
DAS>    cout << len << endl;
DAS>}
DAS>


DAS> Выдает 5. Поэтому я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни


Расшифруем тело функции main
// локальные статические переменные находятся в сегменте данных модуля
static bool    __main_len__init = false;
static size_t  __main_len;

void main()
{
  if(!__main_len__init)
  {
    __main_len_init = true;
    __main_len = strlen("hello");
  }

  cout << ((const size_t)__main_len) << endl;
}


Компилятор не может вычислить strlen(xxx) на стадии компиляции. Хотя бы потому, что функцию можно переопределить.
size_t strlen(const char* s)
{
  return 1; // вот так, в отладочных целях
}

А поскольку она находится в другом модуле (а, может быть, вообще в другой библиотеке), то как ты узнаешь ее значение?
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.