I am trying to have an array, which has a defined size known during compile time.
const uint8_t a[2] = {0, 127}; // Fine
const uint8_t aRange = a[1] - a[0]; // Fine
double sums[aRange]; //Fails
But this fails by gcc with
error: array bound is not an integer constant before ‘]’ token.
As a workaround I intend to use macro variables. But would like to know if there is any logic behind it. There is this answer, which is most related. However, according to the answer, it should have worked.
asked Mar 15, 2020 at 15:35
2
aRange
is a constant integer, but not an integer constant. Isn’t English a fun language?
- C11 §6.4.4.1 Integer constants
- C11 §6.6 Constant expressions ¶6
- An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants,
sizeof
expressions whose results are integer constants,_Alignof
expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to thesizeof
or_Alignof
operator. - 117) An integer constant expression is required in a number of contexts such as the size of a bit-field member of a structure, the value of an enumeration constant, and the size of a non-variable length array. Further constraints that apply to the integer constant expressions used in conditional-inclusion preprocessing directives are discussed in 6.10.1.
- An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants,
- C11 §6.7.6.2 Array declarators — one of the more inscrutable parts of the standard. (¶2 is a constraint; ¶4 and ¶5 specify the semantics of array declarators.)
- ¶2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.
- ¶4 If the size is not present, the array type is an incomplete type. If the size is
*
instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;143) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.) - 143) Thus,
*
can be used only in function declarations that are not definitions (see 6.7.6.3). - ¶5 If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by
*
; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. Where a size expression is part of the operand of asizeof
operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated.
At file (global) scope, you must have an integer constant expression for the dimensions of an array. In a local variable in C99 or later, what you’ve written would be OK for a VLA (variable-length array).
You could work around this with:
enum { A_MIN = 0, A_MAX = 127 };
const uint8_t a[2] = { A_MIN, A_MAX };
const uint8_t aRange = a[1] - a[0];
double sums[A_MAX - A_MIN];
In C, you can’t write const uint8_t aRange = a[1] - a[0];
at file (global) scope, so your code should have been OK unless you’re using an antiquated C compiler that doesn’t recognize C99 or later (or it defines __STDC_NO_VLA__
).
answered Mar 15, 2020 at 15:42
Jonathan LefflerJonathan Leffler
718k138 gold badges893 silver badges1260 bronze badges
2
Jonathan’s answer is accepted. As a workaround I used macros though.
#define A_MIN 0
#define A_MAX 127
const uint8_t a[2] = {A_MIN, A_MAX};
const uint8_t aRange = A_MAX - A_MIN;
double sums[aRange];
answered Mar 15, 2020 at 15:56
1
error: array bound is not an integer constant before ‘]’ token. How to make the variable be the length.
#include<iostream>
using namespace std;
int e;
int a()
{
int b=3;
return b;
}
e=a();
int d[e]={12,2,3};
int main()
{
cout<<d[4]<<endl;
return 0;
}
asked May 4, 2017 at 12:30
Thomas LiThomas Li
711 silver badge5 bronze badges
8
An assignment such as e=a();
cannot exist outside a function.
int d[e];
is also not valid C++ as e
needs to be a compile time evaluable constant expression.
So compilation fails with an albeit cryptic error.
Note that the behaviour of d[4]
will be undefined due to your attempting to access an element outside the bounds of an array.
answered May 4, 2017 at 12:41
BathshebaBathsheba
230k33 gold badges356 silver badges475 bronze badges
1
Try this:
#include <iostream>
using namespace std;
int a(){
int b = 3;
return b;
}
int main(){
int e;
e = a();
int d[e] = {12,2,3};
cout << d[0] << endl;
return 0;
}
As you can see, the size of the vector is just 3 (remember that in c++ the 0 counts as a position), so in this case you just can print 3 values, d[0],d[1],d[2]
, remember that you can not assign a value outside of a function. Also if you plan to assign a global variable to array bound, it has to be constant. Like this: const int e = 3;
, hope it helps.
answered Aug 4, 2018 at 18:06
4
Zigfrid 11 / 11 / 1 Регистрация: 24.11.2015 Сообщений: 359 |
||||||||
1 |
||||||||
В чем ошибка при передачи статического массива в функцию12.11.2016, 16:44. Показов 7932. Ответов 3 Метки нет (Все метки)
Не кидайте камни за использование глобальных переменных и статических двумерных массивов.
а получаю вот такое:
__________________
0 |
mat_for_c 223 / 213 / 80 Регистрация: 26.04.2013 Сообщений: 972 |
||||
12.11.2016, 17:04 |
2 |
|||
1 |
4978 / 3085 / 456 Регистрация: 10.11.2010 Сообщений: 11,164 Записей в блоге: 10 |
|
12.11.2016, 17:05 |
3 |
Написано же тёмным по светлому: array bound is not an integer constant before ‘]’ token Суть: размерность массива не является константой.
1 |
Zigfrid 11 / 11 / 1 Регистрация: 24.11.2015 Сообщений: 359 |
||||||||||||
12.11.2016, 17:17 [ТС] |
4 |
|||||||||||
Все поправил, спасибо!
Что не так с потоками вывода? Добавлено через 8 минут
а не
1 |
|
|
|
Объявление массива, размер которого приводится из вещественного числа к целому
, Просьба помочь разобраться
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Member Рейтинг (т): 21 |
Всем добрый день! Самая краткая выдержка из некой вычислительной программы const double hstep = 2.5e-2; #define HSTEP 2.5e-2 const unsigned int maxh = (unsigned int)(1 / hstep) + 3; const unsigned int MAXH = (unsigned int)(1 / HSTEP) + 3; double f[maxh]; // <— ERROR here double F[MAXH]; // OK! int main(int argc, char *argv[]) { double f[maxh]; // OK too!!! ===8-000 return 0; } Почему получаю ошибку: tmp.cpp:7:14: ошибка: array bound is not an integer constant before ‘]’ token ?? Может быть знатоки ткнут носом в стандарт?! Читаю ISO 9899:1999 (он же C99), пока нашел только похожий пункт в разделе Array declarators (6.7.5.2 пункт 5), If the size is an expression that is not an integer constant expression: if it occurs in a но он не объясняет причины появления ошибки. Скажите, какое семантическое правило я упускаю? Заранее спасибо. Сообщение отредактировано: grgdvo — 14.01.13, 23:01 |
NeoApostol |
|
Может ты что упустил? |
Бублик |
|
#define maxh 1000 |
chooch |
|
Для указания размера массива должна использоваться целочисельная константа, а не переменная, т.к. размер должен быть известен на этапе компиляции. |
NeoApostol |
|
Цитата chooch @ 15.01.13, 01:14 должна использоваться целочисельная константа а у него разве она не константа? |
leo |
|
Цитата NeoApostol @ 14.01.13, 23:53 Читаю ISO 9899:1999 (он же C99), пока нашел только похожий пункт в разделе Array declarators (6.7.5.2 пункт 5),… Глянь строчкой выше, п.4 Цитата If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. и далее п.10 EXAMPLE 4 Цитата Array objects declared with the static or extern storage-class specifier cannot have a variable length array (VLA) type. Что есть Integer constant expression см.6.6 Constant expressions, п.6 Сообщение отредактировано: leo — 15.01.13, 06:44 |
grgdvo |
|
Member Рейтинг (т): 21 |
2leo: 2NeoApostol: |
QraizerOnline |
|
Moderator Рейтинг (т): 520 |
Вообще, я бы не советовал связываться с плавающей точкой в подобных вот случаях. Погрешность вычисления, даже и в компайл-тайм, может привести к тому, что размер массива будет отличаться на 1 от задуманного , а это уже довольно далеко от стандартных ошибок округления для double, не правда ли? Добавлено 15.01.13, 13:19 |
Алексей_Л |
|
В LWS (GCC 4.7.2) код успешно собирается при -std=c++11, а вот при -std=c++03 появляется описанная ошибка. |
grgdvo |
|
Member Рейтинг (т): 21 |
Цитата leo @ 15.01.13, 06:42 Глянь строчкой выше, п.4 и далее п.10 EXAMPLE 4 Цитата Qraizer @ 15.01.13, 13:12 По теме — С++03, раздел 5.19 Constant expressions, пункты 1-3.
Парни, спасибо! |
grgdvo |
|
Member Рейтинг (т): 21 |
Цитата Qraizer @ 15.01.13, 13:12 И эта… попробуй добавить static к переменной hstep. Та же ошибка! Трактую положительно, как верное следование стандарту в части пункта 5.19 абзац 2 (C++2003). Все таки стандарт мутно написан, три дня потребовалось, чтобы уложилось! |
QraizerOnline |
|
Moderator Рейтинг (т): 520 |
А что там верного, если не секрет? По-моему, компилиться должно. Добавлено 22.01.13, 20:47 |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- C/C++: Общие вопросы
- Следующая тема
[ Script execution time: 0,0340 ] [ 16 queries used ] [ Generated: 9.02.23, 12:01 GMT ]
I am trying to implement a stack using an array but I receive an error.
class Stack{
private:
int cap;
int elements[this->cap]; // <--- Errors here
int top;
public:
Stack(){
this->cap=5;
this->top=-1;
};
The indicated line has these errors:
Multiple markers at this line
- invalid use of 'this' at top level
- array bound is not an integer constant before ']' token
What am I doing wrong?
4 Answers
In C++, the size of an array must be a constant known at compile-time. You’ll get an error if that isn’t the case.
Here, you have
int elements[this->cap];
Notice that this->cap
isn’t a constant known at compile-time, since it depends on how big cap
is.
If you want to have a variably-sized array whose size is determined later on, consider using std::vector
, which can be resized at runtime.
Hope this helps!
You cannot use this
in the declaration like that.
this
is a constant pointer passed to non-static methods in your class. It does not exist outside of that scope.
Such array declarations need constant values/expressions for the size. You don’t want that, you want a dynamicly sized container. The solution is to use a std::vector
.
Since other have already explained the cause of this issue, here is a possible solution to resolve it. Since it seems you may not know the array size at compile time and the assignment may restrict the use of std::vector<int>
consider using a pointer implementation.
#include <algorithm>
class Stack{
private:
int cap;
int* elements; // use a pointer
int top;
public:
Stack(){
this->cap=5;
this->top=-1;
elements = new int[this->cap];
}
Stack(const Stack& s)
: cap(s.cap) , top(s.top), elements(NULL)
{
if(cap > 0) {
elements = new int[cap];
}
std::copy(s.elements , s.elements + cap, elements );
}
Stack& operator=(Stack s) {
swap(s, *this);
return *this;
}
~Stack() {delete [] elements;}
friend void swap(Stack& first, Stack& second)
{
using std::swap;
swap(first.top, second.top);
swap(first.cap, second.cap);
swap(first.elements, second.elements);
}
};
Change
int elements[this->cap];
to
int* elements=new int[cap]
Почему компилятор ругается на массив, размерность которого задается статической константой?
Здравствуйте, объявляю следующую структуру:
struct Packet
{
static const int bytes_for_content; //определяется в соотв-ем cpp файле
//...
char content[bytes_for_content]; //это компилятору и не понравилось
};
Подскажите, что не так.
-
Вопрос заданболее трёх лет назад
-
535 просмотров
Пригласить эксперта
Размер полей структуры определяется во время компиляции, а значение константе присваивается во время выполнения программы, вот и ругается. Используйте #define для таких вещей.
struct Packet
{
static const int bytes_for_content;
//...
char content[bytes_for_content]; //это компилятору и не понравилось
};
const int Packet::bytes_for_content = 100;
Как-то так компилятору должно понравиться.
Всем спасибо за участие, хотя по правде в этой теме я до конца так и не разобрался и в своей программе для констант использовал анонимный enum.
-
Показать ещё
Загружается…
09 февр. 2023, в 14:22
1500 руб./за проект
09 февр. 2023, в 13:58
2000 руб./за проект
09 февр. 2023, в 13:28
777 руб./за проект
Минуточку внимания
- Forum
- Beginners
- array bound is not an integer constant b
array bound is not an integer constant before
Please Help me When ever
Getting error “array bound is not an integer constant before ‘]’ token”
#include <iostream>
using namespace std;
int maxr;
int maxc;
void readmatrix(int m[maxr][maxc]); // size depend upon input of maxr and
// maxc
main()
{
cout<<«enter Number of Row :»;
cin>>maxr;
cout<<«enter Number of columb :»;
cin>>maxc;
}
Last edited on
you declare an array with index specified with non constant variable.
when you declare 2d array , the 2nd index must be specified only with a number or a constant variable.
Wait , is your array dynamic or static … most likely i’ll guess it’s static and if that’s the case you’re not allowed to do this
|
|
That only works for dynamic arrays, static arrays dimensions must be const values, so your variables in main should be like
|
|
also, it is a good habit to call global var with scope operator
Topic archived. No new replies allowed.