Specifying global array size with const int

  • Thread starter Bilgehan.Balban
  • Start date
B

Bilgehan.Balban

Hi,

The following code:

#include <stdio.h>

// const int const_asize = 10;
#define define_asize = 10;

int array[define_asize] = {1,2,3,4,5,6,7,8,9,0};

int main(int argc, char * argv[])
{

return 0;
}

Using the #define compiles with no errors, however if you replace it
with the constant variable, I get the following error:

"error: variable-size type declared outside of any function"
"error: variable-sized object may not be initialized"

this is on gcc compiling with the following: gcc -o consttest main.c
adding a -std=c99 does not make any difference.

So the compiler differentiates between a literal and a const int when
they're declared global, but make no distinction when they're local. My
question is, is this standard C behaviour? i.e. Has it been defined as
part of C to refuse to compile above code with a const int specifying
array size, when the array is declared global?

Thanks,
Bahadir
 
A

Alexei A. Frounze

....
// const int const_asize = 10;
#define define_asize = 10;

int array[define_asize] = {1,2,3,4,5,6,7,8,9,0};
....

IMO, what you're trying to do is C++, which is not C.

Alex
 
E

Emmanuel Delahaye

Hi,

The following code:

#include <stdio.h>

// const int const_asize = 10;
#define define_asize = 10;

int array[define_asize] = {1,2,3,4,5,6,7,8,9,0};

You don't need the size. The compiler can count the initializers and
size the array for you :

int array[] = {1,2,3,4,5,6,7,8,9,0};

You can retreive the size by applying the definition of an array
(sequence of elements of the same size), hence :

size_t n = sizeof array / sizeof array[0];

or

size_t n = sizeof array / sizeof *array;

which is easily macroizable to the handy:

#define NELEM(a) (sizeof(a)/sizeof*(a))
int main(int argc, char * argv[])
{

return 0;
}

Using the #define compiles with no errors, however if you replace it
with the constant variable, I get the following error:

"error: variable-size type declared outside of any function"
"error: variable-sized object may not be initialized"

Yes. In C, the array sizer must be a constant expression
(C99 allows VLA under certain conditions. Note that today's
implementations of VLA are broken, even with gcc 4.x).
this is on gcc compiling with the following: gcc -o consttest main.c
adding a -std=c99 does not make any difference.

Obviously, VLA are not permitted on static arrays.
So the compiler differentiates between a literal and a const int when
they're declared global, but make no distinction when they're local. My
question is, is this standard C behaviour? i.e. Has it been defined as
part of C to refuse to compile above code with a const int specifying
array size, when the array is declared global?

Yes, it's conforming with C99.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
K

Keith Thompson

The following code:

#include <stdio.h>

// const int const_asize = 10;
#define define_asize = 10;

int array[define_asize] = {1,2,3,4,5,6,7,8,9,0};

int main(int argc, char * argv[])
{

return 0;
}

Using the #define compiles with no errors,

No, it doesn't, but if you change the line
#define define_asize = 10;
to
#define define_asize 10
it does compile.

This isn't just nitpicking. If you post code to this newsgroup,
*please* cut-and-paste the actual code that you fed to the compiler;
don't try to re-type it. The more time we spend trying to distinguish
between a possible typo and whatever is actually causing the problem
you're asking about, the less time we can spend answering your
question.

(Incidentally, it's traditional for macro names to be in all-caps,
e.g.:

#define DEFINE_ASIZE 10
int array[DEFINE_ASIZE] = {1,2,3,4,5,6,7,8,9,0};
however if you replace it
with the constant variable, I get the following error:

"error: variable-size type declared outside of any function"
"error: variable-sized object may not be initialized"

this is on gcc compiling with the following: gcc -o consttest main.c
adding a -std=c99 does not make any difference.

Right. The keyword "const" doesn't create a constant. It should
really be called something like "readonly". The way to create a true
constant is either to use #define, or, for a value that fits in an
int, an enum declaration:

enum { asize = 10 };
int array[asize] = {1,2,3,4,5,6,7,8,9,0};

The latter is probably an abuse of enum types, but it's a fairly
common idiom.

The lack of a good way to create genuine constants in C is arguably a
flaw in the language, but we're stuck with it.
So the compiler differentiates between a literal and a const int when
they're declared global, but make no distinction when they're local. My
question is, is this standard C behaviour? i.e. Has it been defined as
part of C to refuse to compile above code with a const int specifying
array size, when the array is declared global?

It does distinguish between a literal and a const int in either
context. The difference is that variable length arrays (VLAs) are
legal in a local context. In the following:

int main(void)
{
#define TEN 10
const int ten = 10;
int arr0[TEN];
int arr1[ten];
...
}

arr0 is an ordinary array, but arr1 is a VLA. As you've seen, if
these declarations appeared outside a function, the declaration of
arr1 would be illegal, simply because you can't have global VLAs.

Note also that VLAs are a new feature in C99, and some compilers may
not yet implement them.

Finally, as someone else has pointed out, you don't need to specify the
size in this case; the size can be inferred from the initialization:

int array[] = {1,2,3,4,5,6,7,8,9,0};
 
B

Bilgehan.Balban

Keith said:
It does distinguish between a literal and a const int in either
context. The difference is that variable length arrays (VLAs) are
legal in a local context. In the following:

int main(void)
{
#define TEN 10
const int ten = 10;
int arr0[TEN];
int arr1[ten];
...
}

arr0 is an ordinary array, but arr1 is a VLA.
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Thank you, this clarified it for me very well. I won't post broken code
next time.

Regards,
Bahadir
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top