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

const array declaration

P: n/a
Hi guys,

In a program (not my own) I encountered the declaration of a constant
pointer to an array consisting of two other const pointers to arrays.
Not quite sure why they do it so complicated, but is it legal? Most
compilers accept it, but one doesn't recognize the rhs as a constant.
What are the requirements for the rhs in the declaration of a const
pointer? Is the following program legal C?

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b}; /* this is the statement in question */
return (0);
}

The error message is
"t.c", line 4: error: initialization: constant expression is expected
for variable: `z'

Thanks in advance,

Herbert
Nov 14 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a

"herbertF" <hf******@yahoo.co.uk> wrote in message
news:8d**************************@posting.google.c om...
Hi guys,

In a program (not my own) I encountered the declaration of a constant
pointer to an array consisting of two other const pointers to arrays.
Not quite sure why they do it so complicated, but is it legal? Most
compilers accept it, but one doesn't recognize the rhs as a constant.
What are the requirements for the rhs in the declaration of a const
pointer? Is the following program legal C?

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b}; /* this is the statement in question */
return (0);
}


Your const was in the wrong spot.

int main(int argc, char *argv[]) {
char const *a[] = {"A"};
char const *b[] = {"B"};
char const **z[] = {a, b}; /* this is the statement in question */
return (0);
}

Works just fine.

Tom
Nov 14 '05 #2

P: n/a
herbertF wrote:

Hi guys,

In a program (not my own) I encountered the declaration of a constant
pointer to an array consisting of two other const pointers to arrays.
Not quite sure why they do it so complicated, but is it legal? Most
compilers accept it, but one doesn't recognize the rhs as a constant.
What are the requirements for the rhs in the declaration of a const
pointer? Is the following program legal C?

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b}; /* this is the statement in question */
return (0);
}

The error message is
"t.c", line 4: error: initialization: constant expression is expected
for variable: `z'


The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."

If you think about it in a wider context, you'll see why
`a' and `b' are not constant. Here's a recursive function
with a similar construct, to help show what's happening:

void func(int x) {
const char *a[] = { "A", "B" };
if (0 <= x && x < 2) {
a[x] = "X";
printf ("func(%d): a[0] = %s, a[1] = %s\n",
x, a[0], a[1]);
func (x + 1);
printf ("func(%d): a[0] = %s, a[1] = %s\n",
x, a[0], a[1]);
}
else {
printf ("func(%d): nothing to do\n", x);
}
}

If you call this function with `func(0)', the output will be

func(0): a[0] = X, a[1] = B
func(1): a[0] = A, a[1] = X
func(2): nothing to do
func(1): a[0] = A, a[1] = X
func(0): a[0] = X, a[1] = B

This shows that two different `a' arrays exist: one in
the outer func(0) invocation, and another in the inner func(1).
You can see that there must be more than one `a[]' because
when the outer func(0) executes `a[0] = "X"' the value of `a[0]'
in the inner func(1) is not affected; likewise when the inner
func(1) sets `a[1] = "X"' it does not change `a[1]' in the
outer func(0). Each `a[]' array comes into existence when its
invocation of func() begins, and ceases to exist when its own
func() returns. Thus, even though `a' is just one identifier,
it designates different array objects at different times and
is therefore not a constant.

If you changed the function to declare the array as

static const char *a[] = { "A", "B" };

you would get a different output altogether:

func(0): a[0] = X, a[1] = B
func(1): a[0] = X, a[1] = X
func(2): nothing to do
func(1): a[0] = X, a[1] = X
func(0): a[0] = X, a[1] = X

In this case there is only one `a[]' array, and any changes
made to it in one func() invocation are seen in the other. The
lifetime of this single `a[]' is no longer tied to the execution
of its containing block; this `a[]' comes into existence before
the program starts executing and continues to exist until the
program terminates. In this case, `a' *is* a constant, because
the identifier refers to just one object for the entire time the
program is running. If the one-and-only-one semantics make sense
for your original program, perhaps the cure is to add the `static'
qualifier.

By the way, the non-complaining compilers are not in error.
A compiler is *permitted* to allow non-constant initializers in
addition to the constant initializers required by the Standard.

--
Er*********@sun.com
Nov 14 '05 #3

P: n/a

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."


Yes it is. There is just a diff between

const char *varname;

and

char const *varname;

The former means the values in varname[...] are constant. E.g.

varname[0] = 'a';

will produce a warning.

In the latter the actual pointer "varname" is constant so

varname = &somebuf;

will produce a warning while

varname[0] = 'a';

will not.

const char const *varname;

will make both constant.

Tom
Nov 14 '05 #4

P: n/a
Tom St Denis <to*@securescience.net> wrote:
"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."

Yes it is. There is just a diff between const char *varname; and char const *varname;
These two forms are absolutely equivalent. For the latter you must
be thinking about something like

char * const varname;
The former means the values in varname[...] are constant. E.g. varname[0] = 'a'; will produce a warning.
.... and invoke undefined behavior since varname is not
pointing at anything, but I digress.
In the latter the actual pointer "varname" is constant so
Not true. See my comment above.
const char const *varname;


This is exactly equivalent to:

const const char *varname;

Which is obviously wrong. Again, what you obviously meant to write:

const char * const varname;

--
Alex Monjushko (mo*******@hotmail.com)
Nov 14 '05 #5

P: n/a
herbertF wrote:
In a program (not my own) I encountered the declaration of a constant
pointer to an array consisting of two other const pointers to arrays.
Not quite sure why they do it so complicated, but is it legal? Most
compilers accept it, but one doesn't recognize the rhs as a constant.
What are the requirements for the rhs in the declaration of a const
pointer? Is the following program legal C?

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b}; /* this is the statement in question */
return (0);
}

The error message is
"t.c", line 4: error: initialization:
constant expression is expected for variable: `z'
Let me try:
cat main.c int main(int argc, char* argv[]) {
const char* const a[] = {"A"};
const char* const b[] = {"B"};
const char* const *z[] = {a, b};
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c

main.c: In function `main':
main.c:6: warning: unused variable `z'

It seems to work just fine.

Nov 14 '05 #6

P: n/a

"Alex Monjushko" <mo*******@hotmail.com> wrote in message
news:c0*************@ID-190529.news.uni-berlin.de...
Tom St Denis <to*@securescience.net> wrote:
"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...

The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."

Yes it is. There is just a diff between

const char *varname;

and

char const *varname;


These two forms are absolutely equivalent. For the latter you must
be thinking about something like

char * const varname;


Yeah, oops.

Tom
Nov 14 '05 #7

P: n/a
nrk
Tom St Denis wrote:

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."
Yes it is. There is just a diff between


Bad Tom!! "Here be dragons" :-)
const char *varname;

and

char const *varname;

The former means the values in varname[...] are constant. E.g.

Nope. Both mean exactly the same thing. Perhaps you wanted to show the
difference between:
const char *varname;
and
char * const varname;

Former is a pointer to a const char, the latter a const pointer to char.
varname[0] = 'a';

will produce a warning.

In the latter the actual pointer "varname" is constant so

varname = &somebuf;

will produce a warning while

varname[0] = 'a';

will not.

const char const *varname;

will make both constant.

Nope. What you're looking for is:
const char * const varname;

Which makes varname a const pointer to const char.

-nrk.
Tom


--
Remove devnull for email
Nov 14 '05 #8

P: n/a
Tom St Denis wrote:

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."
Yes it is. There is just a diff between

const char *varname;

and

char const *varname;


No, not really. Both mean: "varname is a pointer to const char".

The former means the values in varname[...] are constant. E.g.

varname[0] = 'a';

will produce a warning.

In the latter the actual pointer "varname" is constant so

varname = &somebuf;

will produce a warning while

varname[0] = 'a';

will not.

const char const *varname;

will make both constant.


No.

const char *varname;

and

char const *varname;

both mean the same thing - a pointer to const char. If you want a const
pointer to char, you need:

char * const varname;

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #9

P: n/a
On Mon, 09 Feb 2004 19:10:46 GMT, "Tom St Denis"
<to*@securescience.net> wrote in comp.lang.c:

"herbertF" <hf******@yahoo.co.uk> wrote in message
news:8d**************************@posting.google.c om...
Hi guys,

In a program (not my own) I encountered the declaration of a constant
pointer to an array consisting of two other const pointers to arrays.
Not quite sure why they do it so complicated, but is it legal? Most
compilers accept it, but one doesn't recognize the rhs as a constant.
What are the requirements for the rhs in the declaration of a const
pointer? Is the following program legal C?

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b}; /* this is the statement in question */
return (0);
}


Your const was in the wrong spot.

int main(int argc, char *argv[]) {
char const *a[] = {"A"};
char const *b[] = {"B"};
char const **z[] = {a, b}; /* this is the statement in question */
return (0);
}

Works just fine.

Tom


There is no difference at all between "const type" and "type const" in
a declarator.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #10

P: n/a
On Mon, 09 Feb 2004 19:43:36 GMT, "Tom St Denis"
<to*@securescience.net> wrote in comp.lang.c:

"Eric Sosman" <Er*********@sun.com> wrote in message
news:40***************@sun.com...
The complaining compiler is correct: `a' and `b' are not
constant expressions.
Despite the spelling, `const' is not
"constant."


Yes it is. There is just a diff between

const char *varname;

and

char const *varname;

The former means the values in varname[...] are constant. E.g.

varname[0] = 'a';

will produce a warning.

In the latter the actual pointer "varname" is constant so

varname = &somebuf;

will produce a warning while

varname[0] = 'a';

will not.

const char const *varname;

will make both constant.

Tom


Look on the bright side, Tom. I did this once in comp.lang.c, years
ago, and had my *ss handed to me. I'll never make that particular
mistake again. I doubt you will, either.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #11

P: n/a
Thanks for the lengthy discussion, but it seems like the question is
still not anwered. What I've learnt from it so far is that the "const"
seems to refer to the array elements, not the pointers themselves.
However, if I add another "const" level, the error message remains the
same. For completeness, here again the original program:

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b};
return (0);
}

and the modified one:

int main(int argc, char *argv[]) {
const char * const a[] = {"A"};
const char * const b[] = {"B"};
const char * const *z[] = {a, b};
return (0);
}

The error message I'm getting is
"t.c", line 4: error: initialization: constant expression is expected
for variable: `z'

Gcc with -pedantic also reports an error:
t.c:4: initializer element is not computable at load time
t.c:4: (near initialization for `z[0]')
t.c:4: initializer element is not computable at load time
t.c:4: (near initialization for `z[1]')

Again the question: is this legal C, and if not, how can it be made
legal?

TiA,

Herbert
Nov 14 '05 #12

P: n/a
hf******@yahoo.co.uk (herbertF) wrote:
Thanks for the lengthy discussion, but it seems like the question is
still not anwered.
Actually, it is.
What I've learnt from it so far is that the "const"
seems to refer to the array elements, not the pointers themselves.
However, if I add another "const" level, the error message remains the
same. For completeness, here again the original program:

int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
What you've also learned is that, despite having the keyword "const"
somewhere in their definitions, these objects are not compile-time
constants, so...
const char **z[] = {a, b};


....they cannot be used as initialisers. No amount of const-qualifying,
whether of the pointers themselves or of their underlying types, can
change that.

Richard
Nov 14 '05 #13

P: n/a
> int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b};
return (0);
}

and the modified one:

int main(int argc, char *argv[]) {
const char * const a[] = {"A"};
const char * const b[] = {"B"};
const char * const *z[] = {a, b};
return (0);
}

The error message I'm getting is
"t.c", line 4: error: initialization: constant expression is expected
for variable: `z'

Gcc with -pedantic also reports an error:
t.c:4: initializer element is not computable at load time
t.c:4: (near initialization for `z[0]')
t.c:4: initializer element is not computable at load time
t.c:4: (near initialization for `z[1]')


Okay, this is really weird. here are the 2 programs I compiled:

(1)
int main(int argc, char **argv) {
const char *a[] = {"A"}; //constant pointer
const char *b[] = {"B"};
const char **z[] = {a, b};
return 0;
}

and (2)
int main(int argc, char **argv) {
const char *const a[] = {"A"}; //constant pointer AND constand data
const char *const b[] = {"B"};
const char *const *z[] = {a,b};
return 0;
}
-----

I compiled both with GCC 3.3.2 like
$gcc -Wall -std=c99 -pedantic const_test_1.c
$gcc -Wall -std=c99 -pedantic const_test_2.c

Only reply I got was:
const_test_1.c: In function "main":
const_test_1.c:4: warning: unused variable `z'
(the same for the other file)

What compiler do you have? I don't see why yours complains :/
Nov 14 '05 #14

P: n/a
I think I found the answer myself. Could somebody comment if my
conclusions are correct? Here are the relevant paragraphs from the
(draft) C99 standard:

6.2.4 Storage duration of objects, paragraph 4:
For such an object that does not have a variable length array type,
storage is guaranteed to be reserved for a new instance of the object
on each entry into the block with which it is associated; the initial
value of the object is indeterminate. If an initialization is
specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes
indeterminate each time the declaration is reached. Storage for the
object is no longer guaranteed to be reserved when execution of the
block ends in any way. (Entering an enclosed block or calling a
function suspends, but does not end, execution of the current block.)

6.6, paragraph 2:

A constant expression can be evaluated during translation rather than
runtime, and accordingly may be used in any place that a constant may
be.

Paragraph 10:

An implementation may accept other forms of constant expressions.

6.7.8 Initialization, paragraph 1:
Syntax
initializer:
assignment-expression
{ initializer-list }
{ initializer-list , }
initializer-list:
designationopt initializer
initializer-list , designationopt initializer
designation:
designator-list =
designator-list:
designator
designator-list designator
designator:
[ constant-expression ]
. identifier

The conclusion is that, because a and b are not static, their
addresses are not known at compile or load time (and may change
between calls to the routine in question), so they are not allowed in
the "designator" part of an initialisation expression, which has to be
a constant expression. Compilers who think they know enough may allow
it (6.6, paragraph 10). To make it fully portable, the static
qualifier has to be present for a and b (in addition to const).

Is this correct?

Btw., I found this about the much discussed question of where in the
line "const" goes:

6.7.3 Type qualifiers, paragraph 8:

If the specification of an array type includes any type qualifiers,
the element type is so qualified, not the array type. If the
specification of a function type includes any type qualifiers, the
behavior is undefined.

H.
Nov 14 '05 #15

P: n/a
herbertF <hf******@yahoo.co.uk> wrote:
Thanks for the lengthy discussion, but it seems like the question is
still not anwered. What I've learnt from it so far is that the "const"
seems to refer to the array elements, not the pointers themselves.
However, if I add another "const" level, the error message remains the
same. For completeness, here again the original program: int main(int argc, char *argv[]) {
const char *a[] = {"A"};
const char *b[] = {"B"};
const char **z[] = {a, b};
return (0);
} and the modified one: int main(int argc, char *argv[]) {
const char * const a[] = {"A"};
const char * const b[] = {"B"};
const char * const *z[] = {a, b};
return (0);
} The error message I'm getting is
"t.c", line 4: error: initialization: constant expression is expected
for variable: `z'


What you failed to learn, however, is that const-qualifying a
variable does not make it a constant, it simply makes it
read-only.

Here is an example:

const int x = 2; /* x is read-only, value is 2 */

int array1[] = {1}; /* 1 is an integer constant, okay */
int array2[] = {x}; /* x is not a constant, not okay! */

Furthermore:

x = 5; /* x is read-only, not okay! */

Now, since the array initializer must be a constant expression,
you are out of luck.

--
Alex Monjushko (mo*******@hotmail.com)
Nov 14 '05 #16

P: n/a
[I snipped some gcc diagnostics from a previous poster here]

In article <news:a8**************************@posting.google. com>
Chris Mantoulidis <cm****@yahoo.com> writes:
Okay, this is really weird. here are the 2 programs I compiled:
It is not all that weird, really :-)

[program 1 snipped, might as well go with the all-"const"-qualified version]and (2)
int main(int argc, char **argv) {
const char *const a[] = {"A"}; //constant pointer AND constand data
const char *const b[] = {"B"};
const char *const *z[] = {a,b};
return 0;
}
-----

I compiled both with GCC 3.3.2 like
$gcc -Wall -std=c99 -pedantic const_test_1.c
$gcc -Wall -std=c99 -pedantic const_test_2.c

Only reply I got was:
const_test_1.c: In function "main":
const_test_1.c:4: warning: unused variable `z'
(the same for the other file)


Try with -std=c89 instead of "-std=c99" (or, equivalently but the
only option available in older versions of gcc, "-ansi -pedantic");
the result should differ. Here is why.

First, "const" in C never means "constant". Its meaning is much
more like "read-only variable". In particular, this means that:

static const int size = 10;
static int a[size];

is *always* an error, in both C89 and C99, because arrays with
"static duration" (not quite the same thing as the "static" keyword)
must have integer constant expressions for any specified sizes.
(But -- while this is off-topic -- we might note that this works
fine in C++, where "const" *does* mean "constant" whenever possible.)
In C, a read-only variable is still a variable, and in some situations
is even *supposed* to change -- just not by being written-on in
the C code you are writing. For instance, the Standard specifically
allows one to write:

extern const volatile int tick_counter;

and arrange for one's system to "hook up" this variable to some
sort of constantly-running system clock (CPU clock, external timer,
or whatever). If this tick counter "ticks" at a known speed,
the clock() function might even be as simple as:

/* NB: the name "tick_counter" is not in the implementor's space
so if this were a real implementation we might want to use some
other variable name. */
clock_t clock(void) { return tick_counter; }

The "const" here means that you, the programmer, cannot change it,
but not that it is constant; and the "volatile" means that something
outside the C code changes it, so that the compiler cannot simply
read the variable once and then "remember" its value forever.

(Without the "volatile", the compiler is still supposed to treat
this as a read-only variable -- not a constant -- but *is* allowed
to assume it never changes as well. If tick_counter is never
explicitly initialized, it is implicitly initially zero, so a
compiler could assume that it is *always* zero and just "return 0"
-- not a very good clock() function.)

With that out of the way, consider the local variables again,
and compare against this code:

int main(void) {
int one = 1, two = 2;
int a[2] = { 1, 2 }; /* works in C89 and C99 */
int b[2] = { one, two }; /* works in C99 but not C89 */

return 0;
}

Here, "one" and "two" are clearly ordinary variables -- they are not
even "const"-qualified read-only variables. The initializers for
"b" are thus not at all constants, but C99 accepts this, just as
both C89 and C99 would accept:

int three = one + two;

The difference here is that C99 has extended the set of values
allowed in "aggregate initializers" -- the set of values in the
braces that initialize a[] and b[]. In C89, all aggregate initializers
had to be constant-expressions; in C99, they may be fully-general
expressions as long as they are initializing "automatic duration"
variables (meaning, pretty much, "ordinary local variables").
This means we can even write:

int f(int zog) {
int arr[4] = { zog, 0, 0, zog + 3 };
... more code ...
}

-- but only in C99, not in C89.

Finally, although it is not used in the original poster's problem,
there is one more significant change in C99 that relates back to
"const" meaning read-only rather than constant. C99 adds a new
type of array called a "variable length array" or VLA. Instead of
making the array "arr" have size 4, we can now do this:

int f(int zog) {
int arr[zog];
...
}

This array has all the usual attributes, plus one more -- its size
is determined at runtime. The expression:

sizeof arr

actually multiplies the value of "zog" by sizeof(int) at runtime.
VLAs have some interesting pitfalls -- the draft C99 standard I
keep handy notes that "unusual" control flow into a block (e.g.,
via a "goto") may not be allocated properly. (More precisely,
it says that "the behavior is undefined" if you jump into a block
that declares a VLA, rather than sequentially executing into it.
There are a couple of different "likely" compilation techniques
that give somewhat different but always bizarre results having to
do with not allocating space at the right point. These include
losing local variables and return addresses when control flows
back out of the block -- your code could crash in such a way that
even a good debugger cannot figure out what happened.)

In any case, VLAs can obscure the fact that "const" variables
are still variables. Compare these three functions:

int f1(int zog) { int arr[zog]; ... }
int f2(int n) { const int zog = n; int arr[zog]; ... }
int f3(void) { const int zog = 12; int arr[zog]; ... }

In f1(), it is obvious that "zog" is a variable. In f2(), "zog"
is *still* a variable, despite being "const"-qualified -- and in
f3(), "zog" is again still a variable, despite being const-qualified
and "obviously" always 12.

In all three functions, "arr" is a VLA, and "sizeof arr" is supposed
to be computed at runtime. In f3(), a C99 compiler is allowed to
"cheat": clearly you promised that zog is always exactly 12 -- by
making it 12 initially, promising never to change it, and not saying
that it might be changed "by magic" ("volatile") -- so the compiler
can replace each "zog" by 12, but only after emitting any required
diagnostics. (In this case, there are no required diagnostics.)

On the other hand, if we change "int arr[zog]" to "static int
arr[zog]", or if we are using a C89 compiler, VLAs are no longer
allowed. In this case, all three variants (f1, f2, f3) require
diagnostics (or more precisely, a C compiler has to emit "at least
one" diagnostic for the translation unit -- producing a single
warning, even though there are at least three errors, suffices to
meet the "letter of the law" as it were).

In summary:

- "const" never means "constant", but rather merely "read-only".

- Variables, even if read-only, are not constant expressions
and cannot be used where constant expressions are required.

- If a C compiler can prove that a read-only variable is always
some particular value, it can substitute in that value, but
only after emitting any required diagnostic.

- C89 requires constant expressions in quite a few more places
than does C99, including aggregate initializers and array sizes.
In particular, C99 removes the silly restriction in C89, where
(as a local variable):
int a = b;
is OK, but:
int a[1] = { b };
is not; and C99 adds variable length arrays.

Thus, if you have a C99 compiler, it may provide a better illusion
of const-qualified variables "acting like" constants, simply because
it allows variables in places C89 did not. But const-qualified
variables are still not constants, and sometimes only a "#define"
will do. (C's actual constants -- members of an "enum" type --
only give you integral constant expressions, i.e., not floating
point, and in practice may not be wide enough, e.g., you probably
cannot get a "long long" constant.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.