Sujet : Re: So You Think You Can Const?
De : ben (at) *nospam* bsb.me.uk (Ben Bacarisse)
Groupes : comp.lang.cDate : 08. Jan 2025, 16:16:03
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <87a5c15ob0.fsf@bsb.me.uk>
References : 1 2 3
User-Agent : Gnus/5.13 (Gnus v5.13)
Julio Di Egidio <
julio@diegidio.name> writes:
On 07/01/2025 23:11, Kaz Kylheku wrote:
On 2025-01-07, Julio Di Egidio <julio@diegidio.name> wrote:
<snipped>
In particular, I am using C90, and compiling with
`gcc ... -ansi -pedantic -Wall -Wextra` (as I have
the requirement to ideally support any device).
>
To the question, I was reading this, but I am not
sure what the quoted passage means:
>
Matt Stancliff, "So You Think You Can Const?",
<https://matt.sh/sytycc>
<< Your compiler, at its discretion, may also choose
to place any const declarations in read-only storage,
so if you attempt to hack around the const blocks,
you could get undefined behavior. >>
An object defined with a type that is const-qualified
could be put into write-protected storage.
>
What do you/we mean by "object" in this context? (Sorry, I do have
forgotten, the glossary to begin with.)
An object (in C) is a contiguous region of storage, the contents of
which can represent values.
Overall, I am surmising this and only this might go write-protected:
>
MyStruct_t const T = {...};
Yes, though you should extend your concern beyond what might be
write-protected. Modifying an object whose type is const qualified is
undefined, even if the object is in writable storage. A compiler may
assume that such an object has not changed because in a program that has
undefined behaviour, all bets are off. For example, under gcc with
almost any optimisation this program prints 42:
#include <stdio.h>
void f(const int *ip)
{
*(int *)ip = 0;
}
int main(void)
{
const int a = 42;
f(&a);
printf("%d\n", a);
}
While this one allocates a "byte-array", i.e. irrespective of how the
pointer we are assigning it is declared:
>
MyStruct_t const *pT = malloc(...);
>
Is my understanding (to that point) correct?
Technically you get an object with no effective type. David's reply
included some references to find out more about the effective type of an
object, but it is safe to say that these only come into play if you are
messing about with the way you access the allocated storage (for example
accessing it as a MyStruct but then later as a floating point object).
More relevant to a discussion of const is to ask what you plan to do
with pT since you can't (without a cast) assign any useful value to the
allocated object.
It is generally better to use a non const-qualified pointer for the
allocation but, when using the pointer, to pass it to functions that use
the right type depending on whether they modify the pointed-to object or
not. For example:
MyStack *sp = malloc(*sp);
...
stack_push(sp, 99);
...
if (stack_empty(sp)) ...
...
stack_free(sp);
we would have
void stack_push(MyStack *sp, int v) { ... }
bool stack_empty(MyStack const *sp) { ... }
void stack_free(MyStack *sp) { ... }
-- Ben.