By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,501 Members | 1,720 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,501 IT Pros & Developers. It's quick & easy.

Find the size of an array

P: n/a
I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>

int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];

printf("new_arr size = %d\n", sizeof(new_arr));

return 0;
}

======================== OUTPUT ====================
[arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:9: warning: ISO C90 forbids variable-size array ‘new_arr’
[arnuld@dune C]$ ./a.out
new_arr size = 4
[arnuld@dune C]$

The program gives correct answer. But Why the warning. sizeof() is compile
time operator then why do I get some warning related to run-time ?


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is UnBlocked now :)
Nov 6 '08 #1
Share this Question
Share on Google+
24 Replies


P: n/a
arnuld said:
I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>

int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];

printf("new_arr size = %d\n", sizeof(new_arr));

return 0;
}

======================== OUTPUT ====================
[arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
test.c: In function ?main?:
test.c:9: warning: ISO C90 forbids variable-size array ?new_arr?
[arnuld@dune C]$ ./a.out
new_arr size = 4
[arnuld@dune C]$

The program gives correct answer. But Why the warning. sizeof() is
compile time operator then why do I get some warning related to run-time
?
gcc is being a little terse here (for understandable reasons). Yes,
sizeof's result is evaluated by the compiler. But, by the time the
compiler is looking at new_arr, it's forgotten all about the sizeof in the
previous line. All it can see is that you've got this asize thing, which
is a const int *but NOT an integral constant expression* - a puzzling
distinction, but a very real one in C.

You can get what you want, however, by cutting out the middle-man:

char arrc[] = "URI";
char new_arr[sizeof arrc / sizeof arrc[0]];

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 6 '08 #2

P: n/a
Michael <mi*****@michaeldadmum.no-ip.orgwrites:
arnuld wrote:
>I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>
int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];
printf("new_arr size = %d\n", sizeof(new_arr));
return 0;
}
======================== OUTPUT ====================
[arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
test.c: In function main:
test.c:9: warning: ISO C90 forbids variable-size array new_arr
[arnuld@dune C]$ ./a.out new_arr size = 4
[arnuld@dune C]$ The program gives correct answer. But Why the
warning. sizeof() is compile
time operator then why do I get some warning related to run-time ?
I have a warning on line 10. Use %lu instead of %d solves it.
It solves it only if size_t happens to be a typedef for unsigned long.
For C90, the portable solution is to use "%lu" *and* convert the
sizeof expression to unsigned long:

printf("new_arr size = %lu\n", (unsigned long)sizeof new_arr);
There is
no problems elsewhere.
As I think has already been mentioned in this thread, asize is not a
constant expression, so it can't be used as an array size in C90. In
C99, new_arr is a VLA (variable-length array). A solution to this
that's portable to both C90 and C99 has already been posted: use
"sizeof arrc / sizeof arrc[0]" directly as the array size.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 7 '08 #3

P: n/a
On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:

gcc is being a little terse here (for understandable reasons). Yes,
sizeof's result is evaluated by the compiler. But, by the time the
compiler is looking at new_arr, it's forgotten all about the sizeof in the
previous line. All it can see is that you've got this asize thing, which
is a const int *but NOT an integral constant expression* - a puzzling
distinction, but a very real one in C.
Now what is the difference between a "const int" and an "inegeral constant
expression". I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.
You can get what you want, however, by cutting out the middle-man:
char arrc[] = "URI";
char new_arr[sizeof arrc / sizeof arrc[0]];

That works fine. Now the real problem is to understand the confusing
distinction.

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Nov 7 '08 #4

P: n/a
arnuld said:
>On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:

>gcc is being a little terse here (for understandable reasons). Yes,
sizeof's result is evaluated by the compiler. But, by the time the
compiler is looking at new_arr, it's forgotten all about the sizeof in
the previous line. All it can see is that you've got this asize thing,
which is a const int *but NOT an integral constant expression* - a
puzzling distinction, but a very real one in C.

Now what is the difference between a "const int" and an "inegeral
constant expression". I can't seem to understand it. May I have 2
examples showing the distinction, so that I can comprehend something out
of them.
A const int is simply an int that you've promised not to change, by
"decorating" it with the word "const".

On the other hand, "integral constant expression" is a formal term that is
relevant to a number of aspects of C programming, amongst them the number
of elements specified in an array (or, in the case of C99, a non-VL array)
at the time of its declaration.

So - what characteristics does an integral constant expression have? "An
integral constant expression shall have integral type and shall only have
operands that are integer constants, enumeration constants, character
constants, sizeof expressions, and floating constants that are the
immediate operands of casts."

Examples of integer constants: 0, 6, 42
Examples of character constants: 'A', 'z', '.'
Example of sizeof expression: sizeof otherarray / sizeof otherarray[0]
Example of floating constants that are the immediate operands of casts:
(int)3.14159

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 7 '08 #5

P: n/a
>Now what is the difference between a "const int" and an "inegeral constant
>expression".
A const int is "const" but not "ant". That is, it's not a compile-time
constant. Why? Because the standard says so. Generally, anything
that requires accessing memory is not a compile-time constant, even
something like "Hello"[0], which should be equal to 'H'.

An "integral constant expression" is constant (including at
compile-time), by definition.

const int not_constant = 42;

switch(c)
{
case 42: /* allowed */
break;
case not_constant: /* not allowed */
break;
}
>I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.
Note that "const" means more that "YOU cannot write it" not "NOBODY
can write it". This is a perfectly logical declaration:

extern const volatile time_t hardware_real_time_clock;

although how you define the variable requires something outside
Standard C if the variable name is descriptive of what it actually
is. It changes by itself with time. YOU may not set it.

Nov 7 '08 #6

P: n/a
On Fri, 07 Nov 2008 07:09:26 +0000, Richard Heathfield wrote:
A const int is simply an int that you've promised not to change, by
"decorating" it with the word "const".

So compiler can change it, I can not ?

On the other hand, "integral constant expression" is a formal term that is
relevant to a number of aspects of C programming, amongst them the number
of elements specified in an array (or, in the case of C99, a non-VL array)
at the time of its declaration.
So - what characteristics does an integral constant expression have? "An
integral constant expression shall have integral type and shall only have
operands that are integer constants, enumeration constants, character
constants, sizeof expressions, and floating constants that are the
immediate operands of casts."
Examples of integer constants: 0, 6, 42
Examples of character constants: 'A', 'z', '.'
Example of sizeof expression: sizeof otherarray / sizeof otherarray[0]
Example of floating constants that are the immediate operands of casts:
(int)3.14159

Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Nov 7 '08 #7

P: n/a
arnuld wrote:
>
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

const is fine when an integral constant expression is not required.

--
Ian Collins
Nov 7 '08 #8

P: n/a
arnuld <su*****@invalid.addresswrites:
>On Thu, 06 Nov 2008 06:54:12 +0000, Richard Heathfield wrote:
gcc is being a little terse here (for understandable reasons). Yes,
sizeof's result is evaluated by the compiler. But, by the time the
compiler is looking at new_arr, it's forgotten all about the sizeof in the
previous line. All it can see is that you've got this asize thing, which
is a const int *but NOT an integral constant expression* - a puzzling
distinction, but a very real one in C.

Now what is the difference between a "const int" and an "inegeral constant
expression". I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.
The tricky thing is that "const" does *not* mean "constant" -- or
rather "const" doesn't mean what C means by "constant". And yes, it's
a poor choice of words, but we're stuck with it, even though the word
"const" obviously is derived from the English word "constant".

"const" really means "read-only". If an object is declared "const",
then attempting to modify it is a constraint violation.

"constant", as in "constant expression", means roughly that the
expression can be evaluated at compile time. I say "roughly" because
that's not how the standard defines it; the standard restricts the
kinds of things that can appear in a constant expression. All
constant expressions can be evaluated at compile time, but not all
expressions that can be evaluated at compile time (by a sufficiently
clever compiler) are "constant expressions". Basically, the language
doesn't require the compiler to be *too* clever.

For example, this is perfectly legal:

const int r = rand();
const time_t start_time = time(NULL);

In both cases the initial value can't be computed until run time; the
"const" says that you're not allowed to modify the object once it's
been initialized. (You can *attempt* do modify it via a tricky
pointer cast, but that's undefined behavior.)

And here's another example where "const" is definitely not constant:

int var = 42;
const int *ptr = &var; /* pointer to const int */
var = 43; /* perfectly legal */
*ptr = 44; /* bzzzt! *ptr is const; you're not allowed
to change it */

Here the object has two "names", var and *ptr. The object itself
isn't read-only, but one of its two "names" is read-only. (The
standard doesn't use the word "name" this way, thus the quotation
marks.)

Another way to look at it: applying "const" to something asks the
compiler to complain if you attempt to modify it.

Now if I declare
const int x = 100;

then the compiler is certainly free to evaluate x at compile time,
replacing any reference to x with a literal 100. That's just a matter
of optimization; it doesn't change the visible behavior of the
program. What the compiler *can't* do is allow you to use "x" in a
context that requires a constant expression -- such as (in C90) an
array length.

(And yes, I'm using the word "allow" a bit loosely here; compilers can
permit such things, but you can't depend on it.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 7 '08 #9

P: n/a
arnuld wrote:
I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>

int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];

printf("new_arr size = %d\n", sizeof(new_arr));

return 0;
}

======================== OUTPUT ====================
[arnuld@dune C]$ gcc4 -ansi -pedantic -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:9: warning: ISO C90 forbids variable-size array ‘new_arr’
[arnuld@dune C]$ ./a.out
new_arr size = 4
[arnuld@dune C]$

The program gives correct answer. But Why the warning. sizeof() is compile
time operator then why do I get some warning related to run-time ?

I have a warning on line 10. Use %lu instead of %d solves it. There is
no problems elsewhere.
Nov 7 '08 #10

P: n/a
Ian Collins <ia******@hotmail.comwrites:
arnuld wrote:
>>
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?

Due to the broken nature of const in C, yes if you want a compile time
constant.
Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const is fine when an integral constant expression is not required.
And haircuts are fine when lunch isn't required. Different beasties,
horses for courses, and stuff.

Phil
--
We must respect the other fellow's religion, but only in the sense and to the
extent that we respect his theory that his wife is beautiful and his children
smart. -- Henry Louis Mencken (1880-1956), American editor and critic
Nov 7 '08 #11

P: n/a
Phil Carmody wrote:
Ian Collins <ia******@hotmail.comwrites:
>arnuld wrote:
>>Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant. The only reason I can think of is oversight.

--
Ian Collins
Nov 7 '08 #12

P: n/a
On Sat, 08 Nov 2008 00:20:11 +1300, Ian Collins <ia******@hotmail.com>
wrote:
>Phil Carmody wrote:
>Ian Collins <ia******@hotmail.comwrites:
>>arnuld wrote:
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant. The only reason I can think of is oversight.
At least one problem is it requires the compiler to keep track of the
value of variable. While expressions like sizeof A / sizeof *A are
computable at compile time, there is no requirement to do so. And
what happens with
const int x = func();

--
Remove del for email
Nov 7 '08 #13

P: n/a
Ian Collins <ia******@hotmail.comwrites:
Phil Carmody wrote:
>Ian Collins <ia******@hotmail.comwrites:
>>arnuld wrote:
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.

const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant. The only reason I can think of is oversight.
Not all const ints, surely? I'm not sure anyone's called
for:

unsigned int foo(const unsigned int bar)
{
struct { unsigned int baz : bar; } a; // BANG!
a.baz=bar;
return a.baz;
}

(Then again, s/: bar/: ' '/ for an apparently legal horror.)
I'd vote for things "ABC"[1] being a compile-time constant with
the same value as 'B', though.

Phil
--
We must respect the other fellow's religion, but only in the sense and to the
extent that we respect his theory that his wife is beautiful and his children
smart. -- Henry Louis Mencken (1880-1956), American editor and critic
Nov 7 '08 #14

P: n/a
Ian Collins <ia******@hotmail.comwrites:
Phil Carmody wrote:
>Ian Collins <ia******@hotmail.comwrites:
>>arnuld wrote:
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant.
How can it be one?

void f(const int x)
{
int a[x];
/* ... */
}

What you mean is probably more like "why can't a const-qualified
integer object, initialised with a constant expression, be used in
constant expressions?".
The only reason I can think of is oversight.
I think that is a very unlikely explanation. Personally, I prefer the
C++ definition but I don't think that was formalised in 1989 when C
got const as a keyword. I can't imagine that the C++ semantics were
not considered by the C99 committee but I hesitate to suggest why they
was rejected.

--
Ben.
Nov 7 '08 #15

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Michael <mi*****@michaeldadmum.no-ip.orgwrites:
>arnuld wrote:
>>I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>
int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];
printf("new_arr size = %d\n", sizeof(new_arr));
return 0;
}
<snip>
>no problems elsewhere.

As I think has already been mentioned in this thread, asize is not a
constant expression, so it can't be used as an array size in C90. In
C99, new_arr is a VLA (variable-length array). A solution to this
that's portable to both C90 and C99 has already been posted: use
"sizeof arrc / sizeof arrc[0]" directly as the array size.
.... and if the size really does benefit from being named (for example
to help explain what is happening, or if it is used in several later
constant expressions) one could always use:

enum { vehicles = sizeof vtable / sizeof vtable[0] };
int engines[vehicles];
int wheels[4 * vehicles];

--
Ben.
Nov 7 '08 #16

P: n/a
Ben Bacarisse <be********@bsb.me.ukwrites:
Keith Thompson <ks***@mib.orgwrites:
>Michael <mi*****@michaeldadmum.no-ip.orgwrites:
>>arnuld wrote:
I want to create a new array of the same size of an array already
available:
#include <stdio.h>
#include <string.h>
int main(void)
{
char arrc[] = "URI";
const int asize = sizeof(arrc) / sizeof (arrc[0]);
char new_arr[asize];
printf("new_arr size = %d\n", sizeof(new_arr));
return 0;
}
<snip>
>>no problems elsewhere.

As I think has already been mentioned in this thread, asize is not a
constant expression, so it can't be used as an array size in C90. In
C99, new_arr is a VLA (variable-length array). A solution to this
that's portable to both C90 and C99 has already been posted: use
"sizeof arrc / sizeof arrc[0]" directly as the array size.

... and if the size really does benefit from being named (for example
to help explain what is happening, or if it is used in several later
constant expressions) one could always use:

enum { vehicles = sizeof vtable / sizeof vtable[0] };
int engines[vehicles];
int wheels[4 * vehicles];
The enum trick only works when the value is with the range of type int.

An alternative is to use a macro:

#define VEHICLES (sizeof vtable / sizeof vtable[0])
int engines[VEHICLES];
int wheels[4 * VEHICLES];

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 7 '08 #17

P: n/a
Ian Collins wrote:
arnuld wrote:
>Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.
Just because "const" does not behave as you want it to does not mean it
is broken. "const" is a type qualifier in the declaration of a
variable; if anything is "broken" it is your understanding.

Nov 7 '08 #18

P: n/a
Martin Ambuhl wrote:
Ian Collins wrote:
>arnuld wrote:
>>Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum
for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Just because "const" does not behave as you want it to does not mean it
is broken. "const" is a type qualifier in the declaration of a
variable; if anything is "broken" it is your understanding.
Rude as ever I see.

There's nothing wrong with my understanding, adopting the C++ definition
in C99 would have broken nothing and saved us from have to use enums (or
worse still, macros) for constants.

--
Ian Collins
Nov 7 '08 #19

P: n/a
Ian Collins <ia******@hotmail.comwrites:
Phil Carmody wrote:
>Ian Collins <ia******@hotmail.comwrites:
>>arnuld wrote:
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.

Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant. The only reason I can think of is oversight.
Another issue is that a const int could also be extern. Perhaps its
definition is buried in a library somewhere, so that the value isn't
known until link time.

lib.c:
const int buffer_size = 17;

app.c:
extern const int buffer_size;
char buf[buffer_size]; /* whoops */

Now, in most cases it would be better to keep the constant in a header,
precisely so that it can be known at compile time:

lib.h:
#define BUFFER_SIZE 17

app.c:
#include "lib.h"
char buf[BUFFER_SIZE];

But I can think of some situations (beyond the scope of the C language
itself, to be sure) where delaying the computation of the constant could
be useful.

(1) The constant is contained in a shared library. You can then change
the constant by updating the shared library and not have to touch the
application that uses it.

(2) To avoid a chicken-and-egg problem, where the value might depend on
the result of the compilation:

$ cat foo.c
#include <stdio.h>
extern const int funcsize;
void func(void) {
printf("This function is %d bytes large!\n", funcsize);
/*
* imagine a lot of complicated stuff here,
* maybe knowing the size of the function will
* help it optimize its cache usage
*/
}
$ cc -c foo.c
$ echo "const int funcsize = `size foo.o |tail -1 |cut -f 1` ;" >funcsize.c
$ cc -c funcsize.c
$ cc -o foo foo.o funcsize.o main.o ...

(3) Since headers and compiled libraries are different files, they can
become out of sync. Here's a way to detect this:

lib.h:
extern const int lib_version;
#define HEADER_VERSION 15
lib.c:
const int lib_version = HEADER_VERSION;
app.c:
#include "lib.h"

if (lib_version != HEADER_VERSION) {
fprintf(stderr, "Version mismatch (header=%d, lib=%d), better recompile\n",
HEADER_VERSION, lib_version);
exit(1);
}

A useful compromise might be a rule that if a const integral variable is
initialized with an integral constant expression, then the variable can
be used as as integral constant expression for the rest of the
translation unit. That would let people do the C++ style

const int buffer_size = 17;
char buf[buffer_size];

while still permitting the uses I mentioned above.
Nov 7 '08 #20

P: n/a
Nate Eldredge wrote:
Ian Collins <ia******@hotmail.comwrites:
>Phil Carmody wrote:
>>Ian Collins <ia******@hotmail.comwrites:
arnuld wrote:
Therefore array depends on an "integral constant expression" not a
constant integer. IOW, should I stop using const and start using enum for
a real constant ?
Due to the broken nature of const in C, yes if you want a compile time
constant.
Is it broken? I find for driver work that const volatile ints do
precisely what I want in C, and don't even let me try to do anything
that I wouldn't want.
const volatile is the exception.

There isn't any good reason why a const integral type can't be a compile
time constant. The only reason I can think of is oversight.

Another issue is that a const int could also be extern. Perhaps its
definition is buried in a library somewhere, so that the value isn't
known until link time.

lib.c:
const int buffer_size = 17;

app.c:
extern const int buffer_size;
char buf[buffer_size]; /* whoops */

Now, in most cases it would be better to keep the constant in a header,
precisely so that it can be known at compile time:
The simple fix there is to make constants unique. C++ does this, so one
can write

const size_t buffer_size = 17;

in a header.
>
A useful compromise might be a rule that if a const integral variable is
initialized with an integral constant expression, then the variable can
be used as as integral constant expression for the rest of the
translation unit. That would let people do the C++ style

const int buffer_size = 17;
char buf[buffer_size];

while still permitting the uses I mentioned above.
and not breaking existing code.

--
Ian Collins
Nov 7 '08 #21

P: n/a

"arnuld" <su*****@invalid.addresswrote in message
news:pa****************************@invalid.addres s...
Now what is the difference between a "const int" and an "inegeral constant
expression". I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.
These points probably already mentioned but to summarise:

"const int x" means something like "readonly int x", except x can be
initialised and can be written to if you try hard enough.

And a compiler usually can't treat it as a compile-time constant, even when
you clearly initialise it, as in for example: const int x = 1200.

To declare a proper named integer constant as in Pascal for example, you
must use:

#define x 1200

or:

enum {x = 1200};

But in both of these cases the scope of x is the entire scope of the file.
And in the enum case, x can only be an integer.

So C doesn't have proper localised named constants. (Which can be a little
frustrating as it would have been a really easy addition to the language:
properconst int asize=sizeof arrc/sizeof arrc[0]; )
Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:rO******************************@bt.com...
You can get what you want, however, by cutting out the middle-man:

char arrc[] = "URI";
char new_arr[sizeof arrc / sizeof arrc[0]];
Defining an intermediate constant is much better, especially with several
same-sized obects to declare, or when the size is also referenced in the
following code.
--
Bartc

Nov 9 '08 #22

P: n/a
"Bartc" <bc@freeuk.comwrites:
"arnuld" <su*****@invalid.addresswrote in message
news:pa****************************@invalid.addres s...
>Now what is the difference between a "const int" and an "inegeral constant
expression". I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.

These points probably already mentioned but to summarise:

"const int x" means something like "readonly int x", except x can be
initialised and can be written to if you try hard enough.
Such a summary should add that modifying a const-qualified object
(like x) is undefined behaviour. You can try, but you should not do
it.
And a compiler usually can't treat it as a compile-time constant, even when
you clearly initialise it, as in for example: const int x = 1200.

To declare a proper named integer constant as in Pascal for example, you
must use:

#define x 1200

or:

enum {x = 1200};

But in both of these cases the scope of x is the entire scope of the file.
And in the enum case, x can only be an integer.

So C doesn't have proper localised named constants. (Which can be a little
frustrating as it would have been a really easy addition to the language:
properconst int asize=sizeof arrc/sizeof arrc[0]; )
That's a little misleading. If the enum is at blocks scope the names
in it are limited to that scope. Since your example above tries to
make asize and int, then a localised enum is up to the job. Had your
example been const size_t = ... then I agree, there is no localised
equivalent.

--
Ben.
Nov 9 '08 #23

P: n/a

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
"Bartc" <bc@freeuk.comwrites:
>enum {x = 1200};

But in both of these cases the scope of x is the entire scope of the
file.
And in the enum case, x can only be an integer.
That's a little misleading. If the enum is at blocks scope the names
in it are limited to that scope. Since your example above tries to
make asize and int, then a localised enum is up to the job.
OK, I didn't know that. So for most purposes it's possible to use:

#define const_int(name,value) enum {name=value}

Then create integer constants with:

const_int (length, sizeof (a)/sizeof(a[0]);

without worrying about re-use of 'length'. That is, where the use of 'enum'
seems inappropriate.

--
Bartc

Nov 9 '08 #24

P: n/a
Bartc wrote, On 09/11/08 11:32:
>
"arnuld" <su*****@invalid.addresswrote in message
news:pa****************************@invalid.addres s...
>Now what is the difference between a "const int" and an "inegeral
constant
expression". I can't seem to understand it. May I have 2 examples
showing the distinction, so that I can comprehend something out of them.

These points probably already mentioned but to summarise:

"const int x" means something like "readonly int x", except x can be
initialised and can be written to if you try hard enough.
You are "not allowed" to write to a const variable, i.e. attempting to
write to one invokes undefined behaviour and anything can happen.
And a compiler usually can't treat it as a compile-time constant, even when
you clearly initialise it, as in for example: const int x = 1200.

To declare a proper named integer constant as in Pascal for example, you
must use:

#define x 1200

or:

enum {x = 1200};

But in both of these cases the scope of x is the entire scope of the file.
And in the enum case, x can only be an integer.
Wrong.

The enum method follows normal scoping rules and so can be local to a
block etc. The #define method is not file scope, it is from the point of
definition to the end of file of undef.
So C doesn't have proper localised named constants. (Which can be a little
frustrating as it would have been a really easy addition to the language:
properconst int asize=sizeof arrc/sizeof arrc[0]; )
<snip>

Not entirely true since enum follows those rules.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Nov 9 '08 #25

This discussion thread is closed

Replies have been disabled for this discussion.