Deutsch   English   Français   Italiano  
<v8tuls$1q1od$1@dont-email.me>

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

Path: ...!feeds.phibee-telecom.net!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
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, 6 Aug 2024 12:48:12 -0700
Organization: A noiseless patient Spider
Lines: 130
Message-ID: <v8tuls$1q1od$1@dont-email.me>
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>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 06 Aug 2024 21:48:13 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="49cc1ebae54dd337cd29762bf6fa6814";
	logging-data="1902349"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19MbBU7Nc4AsYQdtew7tneMd585QnRwUIU="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:LK+TgWURWKWbER6pEy+hNUyFSmQ=
Content-Language: en-US
In-Reply-To: <875xsdc2jq.fsf@bsb.me.uk>
Bytes: 6297

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:

struct device_prv_vtable {
   int (*fp_read) (void* const, void*, size_t);
   int (*fp_write) (void* const, void const*, size_t);
};

// impl...
static int usb_drive_device_read(void* const, void*, size_t);
static int usb_drive_device_write(void* const, void const*, size_t);


int usb_drive_device_read(
  void* const self_,
  void* buf,
  size_t size
) {
   struct usb_drive* const self = self_;
   printf("usb_drive_device_read(%p, %p, %lu)\n",
     (void*)self, buf, (unsigned long)size);
   return 0;
}


int usb_drive_device_write(
  void* const self_,
  void const* buf,
  size_t size
) {
   struct usb_drive* const self = self_;
   printf("usb_drive_device_write(%p, %p, %lu)\n",
     (void*)self, buf, (unsigned long)size);
   return 0;
}