I am creating an array on stack as
static const int size = 10;
void foo() {
..
int array[size];
..
}
However, I get the compile error: "expression must have a constant value", even though size is a constant. I can use the macro
#define SIZE (10)
But I am wondering why size marked const causes compilation error.
In C language keyword const has nothing to do with constants. In C language, by definition the term "constant" refers to literal values and enum constants. This is what you have to use if you really need a constant: either use a literal value (define a macro to give your constant a name), or use a enum constant.
(Read here for more details: Shall I prefer constants over defines?)
Also, in C99 and later versions of the language it possible to use non-constant values as array sizes for local arrays. That means that your code should compile in modern C even though your size is not a constant. But you are apparently using an older compiler, so in your case
#define SIZE 10
is the right way to go.
The answer is in another stackoverflow question, HERE
it's because In C objects declared with the const modifier aren't true
constants. A better name for const would probably be readonly - what
it really means is that the compiler won't let you change it. And you
need true constants to initialize objects with static storage (I
suspect regs_to_read is global).
if you are on C99 your IDE compiler option may have a thing called variable-length array (VLA) enable it and you won't get compile error, efficiently without stressing your code though is with MALLOC or CALLOC.
static const int size = 10;
void foo() {
int* array;
array = (int *)malloc(size * sizeof(int));
}
Related
Is the following legal?
const int n=10;
static int array[n];
If, yes, then why and how?
Note that in C language const objects do not qualify as constants. They cannot be used to build constant expressions. In your code sample n is not a constant in the terminology of C language. Expression n is not an integral constant expression in C.
(See "static const" vs "#define" vs "enum" and Why doesn't this C program compile? What is wrong with this? for more detail.)
This immediately means that your declaration of array is an attempt to declare a variable-length array. Variable length arrays are only allowed as automatic (local) objects. Once you declare your array with static storage duration, the size must be an integral constant expression, i.e. a compile-time constant. Your n does not qualify as such. The declaration is not legal.
This is the reason why in C language we predominantly use #define and/or enum to introduce named constants, but not const objects.
const int n=10;
static int array[n];
This code will encounter an error :
storage size of ‘array’ isn’t constant static int array[n];
^
Static memory allocation refers to the process of reserving memory at compile-time before the associated program is executed, unlike dynamic memory allocation or automatic memory allocation where memory is allocated as required at run-time.
const in C donot make that variable available in compile-time.
Statement like this would not generate that error:
static int array[10];
So, the statement that you have written is illegal or it encounter error while compiling the program.
static vars must ve allocated in COMPILE time, and thus their size and initialization value if any MUST be known at compile time. One could argue that using compile time optimizations the n var would/could be replaced with the constant value 10, and thus it might be possible to successfully compile that specific case.
static const int LOG_MAX = 31;
static int log_table[LOG_MAX];
This code is inside of a function in C. When I try to compile I get the error:
"main.c:19:16: error: storage size of 'log_table' isn't constant".
I don't understand this since LOG_MAX is const.
Just to clarify this is C code and I am using GCC.
In older C and C++ standards, the array bounds of an array had to be a constant literal evaluated at compile time. A const variable isn't necessary evaluated at compile time, it could be created in runtime as a local variable. Also, as pointed out in another answer, const should actually be regarded read-only rather than anything else.
In all C and C++ standards, static arrays must always have their size set using a constant literal. (Or to be picky, this applies to any variable with static storage duration)
In newer C standards (C99, C11) however, the code you posted is perfectly fine if you leave out the static keyword. It will then create a variable-length array (VLA), which may or may not be what you wanted to do.
I'm not sure about the latest C++11 standard, but as far as I know it does not support VLAs.
const does not mean constant in C but rather read-only. LOG_MAX is not a constant in your program.
Here are two ways to have a constant:
#define LOG_MAX 31
or
enum {
LOG_MAX = 31
};
This isn't valid C, even though the int is const and static.
I would recommend doing something like
#define LOG_MAX 31
static int log_table[LOG_MAX];
This fails since a const int variable is not considered a compile-time constant in C.
But since the array is going to be static, you can be sure that the "full" declaration is always available, i.e. it's never going to be referenced through a pointer. Thus, you can inline the size and use sizeof in all places where you wanted to use LOG_MAX:
static int log_table[32];
and then elsewhere in the same function:
const size_t log_max = sizeof log_table / sizeof *log_table;
This keeps the "magic constant" around, but only in one place and its purpose should be pretty clear given the way the log_table is used. This is all inside a single function, after all, it's not scary global data.
You should use the preprocessor :
#define LOG_MAX 31
static int log_table[LOG_MAX];
I am fairly new to C and I don't understand why the following two statements do not create the same result:
char *fields[14] = {NULL};
const int num_fields = 14;
char *fields[num_fields] = {NULL};
Option 1 works, but option 2 does not. It says "variable-sized object may not be initialized" and it gives a warning "warning: excess elements in array initializer". I use gcc 4.2.1 on OSX.
Thanks for sharing your thoughts!
The second object is called a VLA (Variable Length Array), well defined by C99. To achieve what you want you can use this:
for (i = 0; i < num_fields; i++)
fields[i] = NULL;
The gist of the issue is that const int num_fields is very different from 14, it's not a constant, it's read-only.
Even if you define num_fields with const keyword, compiler interprets it as variable only. you can have alternative for this by defining following macro:
#define num_fields 14
char *fields[num_fields] = {NULL};
Although num_fields has a const qualifier, it is still considered a variable by the compiler.
Therefore, you are attempting to declare a variable-sized array, and initialisers (the {NULL} part) cannot be used in conjunction with them.
Your construction works in C++, where a const int will be treated as a compile-time constant ("constant expression"), and hence available for use as a compile-time array size.
(This aspect was one of B. Stroustrup's design goals for C++, to eliminate the need for compile-time macros if possible)
However in C, your definition of "num_fields" effectively declares a read-only memory location with your preset value, and hence is not under C rules a "constant expression" valid at compile time, and hence may not be used as an array size at the outermost 'program' scope.
When I tried this code it works:
const int i = 5;
int main() {
int arry[i];
}
Even though this didn't work:
const int i = 5;
int arry[i];
int main() {
}
I have read all posts here about arrays with constant sizes, but I can't understand why when declaring arry in main it works.
The issue here is that const in C doesn’t result in a true constant.
When you write const int i = 5 what you have is a read-only variable and not a constant. In C99 an array dimensioned with i is a variable length array (VLA). VLAs are only available for stack allocated variables, hence the compilation error you see.
If you need an array with global scope you should switch to a macro.
#define ARRAY_SIZE 5
int arry[ARRAY_SIZE];
This is valid because 5 is a literal which is a true constant.
In fact, even for an array of automatic storage (i.e. stack allocated local variable) you should avoid a VLA since they incur a runtime overhead.
Version 2 is simply not valid C, since i is a read-only variable rather than a true compile-time constant. If you wanted to make it work, you could use malloc and free (or a #define for the size).
Version 1 uses a variable-length array, which is standard feature of C99. gcc supports this syntax in pre-C99 code as an extension. If you compiled your code as C90 and turned on -pedantic, you'd get a warning that ISO C90 forbids variable length array ‘arry’.
const int size = 10; // realna ilość danych
int tablica[size+1];
i have:
variable-size type declared outside of any function
Use
#define size 10
instead of a const int. The latter is not a compile-time constant in C, but a variable that cannot be assigned to (unless via a pointer and a cast to get rid of const).
(This is a difference between C and C++.)
You could use an enum.
enum
{
size = 10
};
int table[size + 1];
Use:
enum { size = 10 };
This is a constant value that can be used in declarations and in case labels and so on. In C99, inside a function, the original code would not be a problem -- your array tablica would be a VLA or variable-length array (and the compiler error message is trying to say "you can't have a VLA outside a function").
Using an enum gives better traceability when you use a debugger on your code; the symbol is included in the symbol table. Typically, C preprocessor symbols are not available to the debugger, so trying to print 'size' when it is #define'd doesn't print an answer; printing 'size' when it is an enum does.
See also: "static const" vs "#define" in C
The error is fairly self-explanatory. You can't declare a variable-length array outside of a function. Although the size of the array you're creating is, in practice, fixed at compile time, you've still technically violated the constraints of the language.
The usual choices are:
Move the array into a function. (Usually the best option, remember globals are to be avoided when possible.)
#define size n where n is the size you want, instead of using an int. (Usually better than "magic numbers", and pretty standard practice in traditional C.)
Use a "magic number" (int tablica[11];). (Usually the last choice, though sometimes it does make more sense.)