Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: A defer mechanism for C
Date: Thu, 31 Dec 2020 02:56:37 -0800
Organization: A noiseless patient Spider
Lines: 141
Message-ID: <86sg7mtfa2.fsf@linuxsc.com>
References: <3a965b75-7eb6-4287-8e19-8969b6628d90n@googlegroups.com> <81f236a7-76cc-499d-91c1-aff76ea471c2n@googlegroups.com> <87v9cwb4di.fsf@nosuchdomain.example.com> <86y2hjwiec.fsf@linuxsc.com> <87y2hj8323.fsf@nosuchdomain.example.com> <868s9hw1os.fsf@linuxsc.com> <87lfdh8116.fsf@nosuchdomain.example.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="cb646d62786edb6c079bbfa1e5ebfce0"; logging-data="10049"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19kGxgZpTsFc3krJQLL/3f6hOF+LKkb16M="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:eG6whLpbaKOXSUOSzKhZcdobJFY= sha1:o7rDoeRq2YYN0lAo8Dt9sq7+USY=
Xref: csiph.com comp.lang.c:157937
Keith Thompson writes:
> Tim Rentsch writes:
>
>> Keith Thompson writes:
>>
>>> Tim Rentsch writes:
>>>
>>>> Keith Thompson writes:
>>>>
>>>>> David Brown writes:
>>>>>
>>>>>> On 20/12/2020 17:46, Christian Hanne wrote:
>>>>>>
>>>>>>>>> I can guarantee, without any doubt whatsoever, that the
>>>>>>>>> fastest malloc implementation you will ever see is the
>>>>>>>>> algorithm used by FreeRTOS's "heap_1" allocator. It will
>>>>>>>>> easily beat MS's algorithm, regardless of the size of the
>>>>>>>>> blocks or the number of them, and it will not waste any
>>>>>>>>> space beyond what you might need for alignment. It will
>>>>>>>>> beat any size-specific pool-based system. However, it has
>>>>>>>>> one weakness - "free" is a no-op.
>>>>>>>
>>>>>>> Forget it, a malloc()-implementation without free isn't a
>>>>>>> malloc()-implementation.
>>>>>>
>>>>>> If it gives memory when you call malloc, it is entirely fine.
>>>>>> There are no specifications that require heap memory to be
>>>>>> re-usable.
>>>>>
>>>>> Well, there's the C standard, which says:
>>>>>
>>>>> The free function causes the space pointed to by ptr to be
>>>>> deallocated, that is, made available for further allocation.
>>>>>
>>>>>> There are a great many programs that allocate memory
>>>>>> dynamically at startup or early on, and never need to free
>>>>>> anything until the end of the program (or for many embedded
>>>>>> systems, simply never end and never need to free anything).
>>>>>> For hosted systems, the OS will clear up the memory when the
>>>>>> program ends. Any effort made by the program or libraries to
>>>>>> track the allocated memory, re-use memory, or free it is then
>>>>>> wasted effort.
>>>>>
>>>>> An implementation in which free() is a no-op might be useful,
>>>>> but it's not conforming.
>>>>
>>>> I believe that the view of the C standard's authors is that
>>>> this choice is one of quality-of-implementation, and not one
>>>> that affects conformance.
>>>
>>> How does the unconditional statement:
>>> The free function causes the space pointed to by ptr to be
>>> deallocated, that is, made available for further allocation.
>>> express that view?
>>
>> AFAICT there is no explicit expression of QOI in any normative
>> text in the C standard. A search of the C11 standard turns up
>> just one occurrence of the word "quality", in a footnote for one
>> of the "Description" paragraphs (specifically, 7.22.2.1 p2) for
>> the rand() function.
>>
>> What we do have however is unspecified behavior. There is no
>> statement of Semantics for memory management library functions,
>> only Descriptions. Many or maybe even most library functions
>> have some amount of unspecified behavior; certainly malloc() and
>> free() do. The Rationale document says the following (note in
>> particular the last part of the last sentence):
>>
>> The terms unspecified behavior, undefined behavior, and
>> implementation-defined behavior are used to categorize the
>> result of writing programs whose properties the Standard does
>> not, or cannot, completely describe. The goal of adopting
>> this categorization is to allow a certain variety among
>> implementations which permits quality of implementation to be
>> an active force in the marketplace as well as to allow
>> certain popular extensions, without removing the cachet of
>> conformance to the Standard. [...]
>>
>> Note furthermore that library function do sometimes have clear
>> statements of requirements, and these are expressed using more
>> direct language. An example may be found in 7.21.6 p1:
>>
>> The formatted input/output functions shall behave as if
>> there is a sequence point after the actions associated
>> with each specifier.
>>
>> There is no doubt here that this statement imposes a specific
>> requirement on a conforming implementation. An important part
>> of that is specificity: there is no question about what
>> behavior is required. Because malloc() and free() give only
>> broad descriptions, and not specific statements of behavior,
>> those functions certainly fall into the realm of unspecified
>> behavior. Without any sort of explicit statement to the
>> contrary, that says to me that the description is meant to
>> give the widest possible latitude, in keeping with what the
>> Standard's authors say in the Rationale document.
>
> How, if at all, would the meaning of the standard change if that
> sentence:
>
> The free function causes the space pointed to by ptr to be
> deallocated, that is, made available for further allocation.
>
> were simply deleted?
It would change in that there would be no expression of the
function's intended purpose.
> I agree that the exact meaning is ambiguous, but I do not believe
> that this or any other straightforward sentence in the standard is
> merely decorative.
The primary purpose of the C standard is to define the language.
Expressing the intended purpose of library functions helps do
that.
The C standard is not meant to define a threshold (except a very
weak one) so we may judge the "goodness" of an implementation.
That this assertion is true may be seen from the famous codicil
of 5.2.4.1 p1
The implementation shall be able to translate and execute at
least one program that contains at least one instance of
every one of the following limits: [...]
This statement, along with what the Rationale document has to say
on the matter, clearly shows that the authors are not interested
in setting a bar for implementations except as it may help sharpen
the definition of the language. The current description of free()
is all that is needed to define the language. Any more stringent
rule, just to limit implementations, is not needed.
I know some people are not happy with this state of affairs, and
would like the C standard to provide more guarantees about how
implementations will behave. The standard's authors, at least in
aggregate, feel otherwise. Personally I think that is a good
decision (at least for C - other languages might be different,
and I haven't thought about the question more broadly). More
importantly though I recognize the decision as reflecting the
authors' idea of what the C standard is meant to express.