Stephen Sprunk said:
On 23-Apr-14 12:39, BartC wrote:
[The meaning of 'const']
Your responses in this thread seem to indicate otherwise.
At minimum, you don't have a "pretty good idea" of how to use it.
Let's see:
(1) It really means 'read-only'
For an object whose type is itself const-qualified, rather than being
merely a pointer to a const-qualified type, it also means "cannot be
modified after initialization with defined behavior".
(2) It's an attribute applied to a type
(3) Such a type can be used pretty much everywhere that a non-const type can
I would say that the following item constitutes an exception to the
preceding item, and they should both therefore be re-written to
acknowledge that relationship.
(4) Attempts to write to an l-value with a read-only attribute raise a
compiler diagnostic, except:
This applies not only to explicit attempts to write to the object, but
also to certain constructs that merely put the object at risk of being
written to. The prime example of this is passing a 'const T*' to a
function where the corresponding parameter has the type 'T*'. That means
that the function could, without containing any constraint violations in
the function itself, attempt to write through that parameter - so the
function call itself has been made a constraint violation. This is
perhaps the single most useful feature enabled by 'const'.
Keep in mind that a diagnostic is required because such uses of
const-qualified types are constraint violations. That also gives an
implementation permission to reject the program. If the implementation
chooses not to reject the program, and if the user chooses to execute
the translated program, the behavior is also undefined. That's the most
seriously negative thing that C standard says about any program construct.
(5) An object with a read-only type attribute can be initialised in its
declaration (even with a runtime value for a non-static object); and:
(6) A function parameter with a read-only type attribute can be initialised
from an argument that has non-read-only attribute
(7) Implicit coercions from non-read-only to read-only versions of the same
type ( T to const T) are allowed.
(8) Implicit coercions from read-only to non-read-only versions of the same
type (const T to T) raise a compiler diagnostic.
More accurately, such conversions do not occur implicitly at all. The
diagnostic message is side-effect of the fact that the conversion did
NOT occur. It is the use of a const-qualified type in a context where it
is incompatible with the required type, that is the actual cause of the
constraint violation.
(9) Read-only attributes can be used by the compiler as optimisation hints,
as well helping to decide which kind of data segments static data can be
stored in.
That is a side-effect of the fact that the use a const-qualified types
in certain contexts leaves the behavior of the entire program undefined,
so that there is no such thing as incorrect behavior in those contexts.
An implementor is therefore free to let the behavior in those contexts
be whatever is most convenient, rather than whatever it is that the
programmer might have thought was reasonable.
(10) Read-only attributes can be applied to any level of any
type-specification, which means a complex type-spec can have any number of
read-only attributes (not including the multiple attributes that some
compilers allow at each level)
You should clarify that you're referring to levels of indirection.
'const' is a type-qualifier, and as such can only appear in locations
where type-qualifiers are allowed by the syntax, though it can be mixed
in with any of the other kinds of declaration specifiers; their relative
order has no significance. What you're referring to is the fact that
'const' has a different meaning depending upon whether it appears to the
left or to the right of any given '*' in the declaration.
(11) Read-only attributes can be applied to scalars, structs and pointers,
but not to arrays.
<nitpick>That's redundant, since pointer types are scalar types. unions
can also be declared 'const'.</nitpick>
Could you provide a citation for the array exception? Perhaps you're
thinking of the _Atomic type-qualifier, for which application to an
array type would be a constraint violation (6.7.3p2)?
(12) Casts can be used to convert read-only to non-read-only and vice versa
If that lot (which is is off the top of my head, so apologies if the terms
aren't quite right) isn't a 'pretty good' summary of how 'const' works, then
I will admit I have absolutely no idea what it does.
It is a pretty good summary; the objections I've raised are relatively
minor - if I wrote up my own summary I'd expect Keith, at least, to be
able find at least as many minor errors in my summary. He's annoyingly
good at finding such errors - but the annoyance is with myself, for
making the errors, not with him, for finding them.
Which makes it all the more confusing that you've said so many
ridiculous things about 'const' that are not justified by any of the
items from the above summary (I'm NOT referring to your subjective
judgment that 'const' is useless). If you can't use the facts you've
listed above to reach correct conclusions about how 'const' is used,
then you don't really understand those facts, even if you can list them
out correctly. Possibly your mistaken belief that use of 'const' calls
for frequent use of (const T*) casts is merely due to your deliberate
lack of experience with using 'const'.