arnuld <su*****@invali d.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_Keit h)
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"