void **abc;
const void **def;
void test(void)
{
def = abc;
}
That in itself doesn't actually explain why it's inappropriate,
particularly when you consider that 'void *' and 'const void *' are
different types but quite acceptible in one direction. I've found the
answer, though:
6.5.16.1, example 3 of the C99 draft I found I-don't-know-where:
const char **cpp;
char *p;
const char c = 'A';
cpp = &p;
*cpp = &c;
*p = 0;
Which makes me wonder, should this be legal?
const char * const *cpp;
char *p;
const char c = 'A';
cpp = &p;
In this case, cpp can't be used to place the address of a pointer to
const into a pointer to non-const. If it happens to find itself
pointing to a non-const pointer that is being used to modify some data,
that's no different from when a const char * points to a non-const char.
gcc doesn't accept it (I'm sure nobody likes hearing "my compiler does
this", but I just don't want any "try it" responses).
> not to mention, a pointer to void qualified by const is useless.
That was just me stripping everything down to the simplest case.
Mantorok Redgormor wrote:
> [...]
> Hope that clears it up for you.
Actually no, you're explaining entirely the wrong thing. I understand
how a compiler works, and how the syntax is interpreted. I'm concerned
with the validity of the specification itself.
Why is it that const is not allowed to be promoted up more than one link
of the chain? The example I cited demonstrates why it can't be allowed
(because you could then construct legal syntax to write to a const
pointer), but if you guard against that hazard with more consts, should
it not then be allowed?
There are a couple of related issues.
One is that you must use a cast to remove constness;
that is intentional since we want the programmer to
have to think about his intention and not accidentally
attempt to modify what might actually be read-only memory.
The other is that (only) the top level of indirection in
a function parameter has const at the next level treated
specially (look up "type category" in the C standard);
that changes the meaning so that such a parameter is in
effect guaranteed *at the caller* to not be used as a
base for modifying the pointed-to object, which enables
certain compiler optimizations and serves as a valuable
self-documenting feature of the function declaration.
Attempts to extend that to deeper levels of indirection
were unsuccessful ("const poisoning" was the common term
for the problem that resulted).
Probably, but what are the exact rules for what's safe and what's not?
Now figure out the rules for the other type qualifiers, volatile and
restrict. Now convince the ISO committee that you've actually
considered everything (aggregates such as arrays and structures add
interesting complications) and gotten the rules exactly right and they
may well be willing to adopt them sometime in the future.
-Larry Jones
He's just jealous because I accomplish so much more than he does. -- Calvin
Douglas A. Gwyn wrote:
> [...] Attempts to extend that to deeper levels of indirection were
> unsuccessful ("const poisoning" was the common term for the problem
> that resulted).
Hmm. Then I don't suppose there's much to be done other than abandon
const and go over to some lint-like tool with extra markup.
Or write my own language, of course.
I hope that anyone going that route appreciates the
advantage of separating concepts that all too often
in C were overloaded on a single keyword. C's
"const" is closer to "readonly" in meaning, while
C++'s "const" is closer to "constant". (Those are
not the same thing, as seen in the weirdness with
function parameters discussed in this thread.)
Douglas A. Gwyn wrote:
> I hope that anyone going that route appreciates the advantage of
> separating concepts that all too often in C were overloaded on a
> single keyword. C's "const" is closer to "readonly" in meaning, while
> C++'s "const" is closer to "constant". (Those are not the same thing,
> as seen in the weirdness with function parameters discussed in this
> thread.)
Well, I have no intention of doing it... but if I did, I'd introduce a
world of clearer type qualifiers. The greater portion of my C
frustrations are about the weakness of its type checking.
>in C were overloaded on a single keyword. C's
>"const" is closer to "readonly" in meaning, while
>C++'s "const" is closer to "constant". (Those are
>not the same thing, as seen in the weirdness with
>function parameters discussed in this thread.)
Whose fault is that the ANSI X3J11 committee didn't preserve the C++
semantics of const?
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de
It's nobody's "fault"; C++ has different concerns,
and the function-interface concern dominated when
the C standard was drafted. The idea was that C
users would be better served by the flavor chosen
for the C standard.
However, one needs some mechanism(s) to esacpe from
strict type checking. Indeed, the aforementioned
"const poisoning" was an instance of problems brought
on by too-strict type rules.
Please elaborate. Why would C users have been inconvenienced if const
meant "constant" and not "read only"?
Douglas A. Gwyn wrote:
> However, one needs some mechanism(s) to esacpe from strict type
> checking. Indeed, the aforementioned "const poisoning" was an
> instance of problems brought on by too-strict type rules.
Well, I'd rather keep them just as strict, but choose semantics that
mean that that strictness doesn't need to be escaped.
Dan Pop wrote:
>> Whose fault is that the ANSI X3J11 committee didn't preserve the C++
>> semantics of const?
Douglas A. Gwyn writes:
>> It's nobody's "fault"; C++ has different concerns,
>> and the function-interface concern dominated when
>> the C standard was drafted. The idea was that C
>> users would be better served by the flavor chosen
>> for the C standard.
Dan Pop wrote:
> Please elaborate. Why would C users have been inconvenienced if const
> meant "constant" and not "read only"?
I may be wrong about this, but I seem to recall some discussion that
adding 'const' in too many places in the language and library would force
too many changes to existing code. I don't remember the logic underlying
this argument, but it was something along the lines that once you use
'const' on your function args, you must propagate the 'const' to all other
functions that you pass these args to, and they must propagate the 'const'
in turn, etc., all the way back to the standard library functions (which,
it turns out, were not much of a problem in this regard). The alternative
would have been excessive use of casts to remove 'const' when calling
other functions. (Doug referred to this as "const poisoning".)
There may also have been mention of the fact that using 'const' args and
auto variables would force large amounts of code to be rewritten when
these values were passed to existing O/S and third-party library functions.
But again, real damage did not seem to materialize in this regard.
-drt
None of this has anything to do with the actual semantics of const
(read only vs constant) and everything to do with the rules concerning
const propagation. These rules do cause the "const poisoning" effect in
C.