Deutsch   English   Français   Italiano  
<87zfpp9s1b.fsf@bsb.me.uk>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!weretis.net!feeder9.news.weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Ben Bacarisse <ben@bsb.me.uk>
Newsgroups: comp.lang.c
Subject: Re: No warning at implicit removal of const. Was: relearning C: why does an in-place change to a char* segfault?
Date: Tue, 06 Aug 2024 23:59:28 +0100
Organization: A noiseless patient Spider
Lines: 87
Message-ID: <87zfpp9s1b.fsf@bsb.me.uk>
References: <IoGcndcJ1Zm83zb7nZ2dnZfqnPWdnZ2d@brightview.co.uk>
	<20240801174026.00002cda@yahoo.com> <v8gi7i$29iu1$1@dont-email.me>
	<slrnvaorkl.34j6.candycanearter07@candydeb.host.invalid>
	<87zfpvfdk4.fsf@nosuchdomain.example.com>
	<v8ii17$2q5p1$1@dont-email.me>
	<87v80ig4vt.fsf@nosuchdomain.example.com>
	<v8jbvj$2vat1$1@dont-email.me> <87le1ed0dl.fsf@bsb.me.uk>
	<v8jp3f$321h8$1@dont-email.me> <875xsfdbhf.fsf@bsb.me.uk>
	<v8pdsn$fgau$1@dont-email.me> <87ttfzb5ar.fsf@bsb.me.uk>
	<v8rd2g$11vvn$2@dont-email.me> <87frribsgs.fsf@bsb.me.uk>
	<v8rkb3$156mh$1@dont-email.me> <875xsdc2jq.fsf@bsb.me.uk>
	<v8tuls$1q1od$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Wed, 07 Aug 2024 00:59:30 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="3b5448cf72f6af8b8a6a12b04ac1cbd8";
	logging-data="2011924"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18lUSeG94I4bMCJt7dOspROjK2BGSHkrpE="
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:+d+hMTZpy3fWyZvDftpOnBCKitY=
	sha1:CsJJ8nnJxDcbB1N7wfoo6vRVUMY=
X-BSB-Auth: 1.14f84e9c195d84e3af8d.20240806235928BST.87zfpp9s1b.fsf@bsb.me.uk
Bytes: 5940

"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:

> On 8/6/2024 4:29 AM, Ben Bacarisse wrote:
>> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
>> 
>>> I must have completely missed it. Sorry about that. Please redefine?
>> It's going to seem silly after all these exchanges.  I simply wanted to
>> know why you chose to use const as you originally posted:
>> | struct object_prv_vtable {
>> |       int (*fp_destroy) (void* const);
>> |       int (*fp_read) (void* const, void*, size_t);
>> |       int (*fp_write) (void* const, void const*, size_t);
>> | };
>> because that looks peculiar (to the point of being arbitrary) to me.
>> You went on to talk about "self" pointers being const pointers to const
>> void, but that was not what you wrote, so it did not address what I was
>> asking about.
>> In general, const qualified argument types are rarely used and are even
>> more rarely used in function (or type) declarations because there have
>> no effect at all in that position.  For example, I can assign fp_destroy
>> from a function declared without the const-qualified parameter:
>>     int destroy(void *self) { /* ... */; return 1; }
>>     ...
>>     vtab.fp_destroy = destroy;
>> or, if I do want the compiler to check that the function does not alter
>> its parameter, I can add the const in the function definition (were it
>> can be useful) even if it is missing from the declaration:
>>    struct object_prv_vtable {
>>          int (*fp_destroy) (void*);
>>          /* ... */
>>    };
>>    int destroy(void *const self) { /* ... */; return 1; }
>>    ...
>>    vtab.fp_destroy = destroy;
>> But if you want the const there so that the declaration matches the
>> function defintion, why not do that for all the parameters?  Basically,
>> I would have expercted either this (just ine const where it matters):
>> struct object_prv_vtable {
>>        int (*fp_destroy) (void *);
>>        int (*fp_read) (void *, void *, size_t);
>>        int (*fp_write) (void *, void const *, size_t);
>> };
>> and the actual functions that get assigned to these pointers might, if
>> you want that extra check, have all their parametera marked const.  Or,
>> for consistency, you might have written
>> struct object_prv_vtable {
>>        int (*fp_destroy) (void * const);
>>        int (*fp_read) (void * const, void * const, size_t const);
>>        int (*fp_write) (void * const, void const * const, size_t const);
>> };
>> even if none of the actual functions have const parameters.
>> Finally, if you had intended to write what you later went on to talk
>> about, you would have written either
>> struct object_prv_vtable {
>>        int (*fp_destroy) (const void *);
>>        int (*fp_read) (const void *, void *, size_t);
>>        int (*fp_write) (const void *, void const *, size_t);
>> };
>> or
>> struct object_prv_vtable {
>>        int (*fp_destroy) (const void * const);
>>        int (*fp_read) (const void * const, void * const, size_t const);
>>        int (*fp_write) (const void * const, void const * const, size_t const);
>> };
>> TL;DR: where you put the consts in the original just seemed arbitrary.
>> I'll also note that the term "const pointer" is often used when the
>> pointer is not const!  It most often mean that the pointed-to type is
>> const qualified.  As such, it's best to avoid the term altogether.
>
> I wanted to get across that the pointer value for the first parameter
> itself should not be modified. I read (void* const) as a const pointer to a
> "non-const" void. Now a const pointer to a const void is (void const*
> const), from my code, notice the first parameter?
>
> I consider the first parameter to be special in this older OO experiment of
> mine. It shall not be modified, so I wrote it into the API:

You could have said that when I asked many posts ago!  I can't see a
sound technical reason to put a const there but that parameter is in
some way different I suppose.  The effect on readers is likely to be a
puzzled, mild confusion.

Note that is not really "in the API" as it is entirely optional whether
the implementation has a const first parameter.

-- 
Ben.