David Brown said:
On 09/04/14 00:27, BartC wrote: [...]
Instead of a simple, logical extension to allow such a declaration,
where it will be completely obvious what it is and what it can do,
you instead propose using a *variable* for the purpose, which so many
issues associated with it that I hardly know where to start! But I
will have a go:
A "const" is not a variable - it is a constant object. So instead of
introducing some sort of new type of constant to the language, I would
rather take the existing const concept and extend it slightly (as it is
in C++) to cover the remaining needs for constants. That is far
simpler, clearer and easier than having a new type of constant - and it
already exists in C++.
You're conflating "const" and "constant" in a context where the
distinction is extremely relevant.
Perhaps - I certainly agree that we must be as clear as possible here.
I think one other aspect that we should make clear is when we are
talking about file level objects, and when we are talking about function
local objects. There is a significant difference in what can and cannot
be done with "const" in these contexts, and I think that is adding to
Bart's confusion.
It's not entirely clear what the word "variable" should mean in C. The
standard doesn't use the term; instead it uses "object". Is a
const-qualified object a "variable"? You could probably get three
different answers from three different people here; mine is that I avoid
using the word "variable" when there's any chance of confusion.
I view "variable" to mean something that can legally be changed after
its creation and initialisation. Thus any object defined as "const"
will be a constant object, and not a variable.
"const" in C simply means "read-only". "Constant" refers to something
that can (and must) be evaluated at compile time, as in "integer
constant" (what some languages call an "integer literal") or a "constant
expression" (an expression that can be used as if it were a literal).
Yes, that's true (AFAIUI). But I think we must carefully distinguish
between file scope const and block scope const, as the rules and effects
are different.
Because a file scope initialised "const" must be initialised by a
"constant expression", and it is read only, the compiler knows its value
at any time - and therefore any use of its value can be replaced by the
compile-time constant expression. The exceptions here are for things
like array dimensions, which C disallows even though the compiler is
guaranteed the required knowledge to generate the code, and C++ can use
the const objects in such circumstances.
At block level (local to a function), const objects become constant
after their initialisation - you cannot legally change them. But
(unless they are "static const") they do not necessarily have
compile-time constant values, and are therefore named read-only copies
of their initialisers.
Remember that
const int r = rand();
is perfectly valid (at block scope); r is const (read-only), but clearly
its value cannot be determined until run time.
Correct - but after its initialisation, and throughout its lifetime, "r"
is constant.
I believe Bart has been thinking mainly of file scope "const", but has
mixed in block scope differences too. I wish I had thought of that
earlier - I think we could have had a clearer and simpler discussion if
the distinction had been made clear.
[...]
"const" is not a hint to the compiler about variables - it is a specific
direction that this object will be constant, and will never be changed.
It's a direction that the object is *read-only*.
[...]
I think you are mixing up the use of "const" in definitions such as
"static const int xyz = 123;", and its use in function arguments
(especially for pointers), such as "size_t strlen(const char* s)".
They're essentially the same thing. In both cases, the "const" asserts
that the relevant object (xyz or *s) will not be modified. In both
case, the compiler can optimize based on that assertion. It just
happens to be able to optimize better when it can see what the initial
(and only) value is.
While that is true, the two uses of "const" here have different effects
because of the different levels of knowledge that the compiler has. I
am trying to concentrate on the effects, implementations and practical
features (and limitations) of "const", rather than the language details.
What the C++ rule does is take an object that's defined to be read-only
and make its name a compile-time constant. IMHO it's a bit of a hack,
but it's a useful one that I'd like to see adopted in C.
Well, at least we agree on what we want in the end!