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.