Path: ...!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: So You Think You Can Const? Date: Mon, 13 Jan 2025 11:46:22 -0800 Organization: A noiseless patient Spider Lines: 62 Message-ID: <86plkq5wfl.fsf@linuxsc.com> References: <874j27qfp7.fsf@nosuchdomain.example.com> <20250110122353.00005377@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Mon, 13 Jan 2025 20:46:26 +0100 (CET) Injection-Info: dont-email.me; posting-host="9eea8443f476a77794ac96904ee9ae64"; logging-data="2119869"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18lLhx2cdRRY/nuK6JHh0Vj2owX1iav7K4=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:L/6yfL02GmFU4+iXOobpHvvGpMc= sha1:gV+UpVN4KlQ0WYHHc0enzi0dQSM= Bytes: 4140 Michael S writes: > On Thu, 09 Jan 2025 23:40:52 -0800 > Keith Thompson wrote: > >> Andrey Tarasevich writes: >> >>> On 01/09/25 12:12 AM, Julio Di Egidio wrote: >>> >>>> I do not understand that: `free` is changing the pointed data, so >>>> how can `const void *` even be "correct"? >>> >>> `free` is destroying the pointed data. >> >> Right. In other words, it causes the pointed-to data to reach the end >> of its lifetime. "Changing" the data generally means modifying its >> value (that's what "const" forbids). >> >> Given: >> >> int *ptr = malloc(sizeof *ptr); >> *ptr = 42; >> printf("*ptr = %d\n", *ptr); >> free(ptr); >> >> After the call to free(), the int object logically no longer exists. >> Also, the value of the pointer object ptr becomes indeterminate. >> Attempting to refer to the value of either ptr or *ptr has undefined >> behavior. > > I believe that the Standard really says that, but find the part about > value of ptr variable ridiculous. It breaks natural hierarchy by which > standard library is somewhat special, but it is not above rules of core > language. free() is defined as function rather than macro. By rules of > core language, a function call can not modify the value of local > variable at caller's scope, unless pointers to the variable was passed > to it explicitly. There is an important distinction here, one I suspect you are either glossing over or missing. The bits in the pointer don't change, but the meaning of those bits can change. To say that a different way, what memory location a pointer object representation (the bits) designates can depend on information outside the pointer object itself, depending on the machine architecture. A natural example is a machine with segmented memory, where "a pointer" consists of a segment number and an offset within the segment. If a free() has been done by marking a particular segment invalid (such as by setting a bit in a global segment table), the bits in the pointer passed to free() don't change, but those bits no longer refer to any memory location. The pointer becomes "indeterminate" even though none of the bits in the pointer have changed. Does that make sense? Editorial sidebar: in my opinion the C standard doesn't describe what is going on here as well as it should. What the C standard says is that the (pointer) object becomes indeterminate. What is really happening is not that the object changes but that the stored bits are no longer a valid value representation. It would be more accurate to say the validity of the object representation changes, starting as valid before the free() and ending up as invalid after the free(). Unfortunately there is some historical baggage tied to the phrasing here, and so the description says the object becomes indeterminate.