Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #41500 > unrolled thread

Does ANSI C allow free() to always be empty?

Started bypartremmaps@gmail.com
First post2014-03-08 22:08 -0800
Last post2014-03-30 04:22 +0000
Articles 20 on this page of 45 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-08 22:08 -0800
    Re: Does ANSI C allow free() to always be empty? Kaz Kylheku <kaz@kylheku.com> - 2014-03-09 06:55 +0000
      Re: Does ANSI C allow free() to always be empty? David Brown <david.brown@hesbynett.no> - 2014-03-10 00:47 +0100
        Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-09 22:37 -0700
          Re: Does ANSI C allow free() to always be empty? David Brown <david.brown@hesbynett.no> - 2014-03-10 10:20 +0100
            Re: Does ANSI C allow free() to always be empty? Keith Thompson <kst-u@mib.org> - 2014-03-10 08:52 -0700
            Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-10 20:51 -0700
              Re: Does ANSI C allow free() to always be empty? Robert Wessel <robertwessel2@yahoo.com> - 2014-03-11 01:08 -0500
              Re: Does ANSI C allow free() to always be empty? David Brown <david.brown@hesbynett.no> - 2014-03-11 12:52 +0100
                Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-12 00:09 -0700
                  Re: Does ANSI C allow free() to always be empty? David Brown <david.brown@hesbynett.no> - 2014-03-12 12:59 +0100
        Re: Does ANSI C allow free() to always be empty? Kaz Kylheku <kaz@kylheku.com> - 2014-03-10 09:01 +0000
      Re: Does ANSI C allow free() to always be empty? Nick Bowler <nbowler@draconx.ca> - 2014-03-10 15:56 +0000
    Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-09 01:11 -0800
      Re: Does ANSI C allow free() to always be empty? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-09 12:39 +0000
        Re: Does ANSI C allow free() to always be empty? gazelle@shell.xmission.com (Kenny McCormack) - 2014-03-09 13:05 +0000
        Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-09 22:28 -0700
          Re: Does ANSI C allow free() to always be empty? Martin Shobe <martin.shobe@yahoo.com> - 2014-03-10 07:27 -0500
            Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-10 20:55 -0700
              Re: Does ANSI C allow free() to always be empty? Martin Shobe <martin.shobe@yahoo.com> - 2014-03-11 08:19 -0500
                Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-11 23:22 -0700
                  Re: Does ANSI C allow free() to always be empty? Martin Shobe <martin.shobe@yahoo.com> - 2014-03-12 08:09 -0500
                    Re: Does ANSI C allow free() to always be empty? James Kuyper <jameskuyper@verizon.net> - 2014-03-12 11:29 -0400
        Re: Does ANSI C allow free() to always be empty? Martin Shobe <martin.shobe@yahoo.com> - 2014-03-10 07:29 -0500
    Re: Does ANSI C allow free() to always be empty? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-09 09:14 +0000
      Re: Does ANSI C allow free() to always be empty? Robert Wessel <robertwessel2@yahoo.com> - 2014-03-10 15:33 -0500
    Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-09 23:05 -0700
      Re: Does ANSI C allow free() to always be empty? Martin Shobe <martin.shobe@yahoo.com> - 2014-03-10 07:43 -0500
        Re: Does ANSI C allow free() to always be empty? gordonb.3qcze@burditt.org (Gordon Burditt) - 2014-03-10 12:05 -0500
          Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-10 20:16 -0700
          Re: Does ANSI C allow free() to always be empty? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 16:27 -0700
        Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-10 21:48 -0700
          Re: Does ANSI C allow free() to always be empty? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-11 05:52 +0000
    Re: Does ANSI C allow free() to always be empty? partremmaps@gmail.com - 2014-03-20 19:14 -0700
      Re: Does ANSI C allow free() to always be empty? Kaz Kylheku <kaz@kylheku.com> - 2014-03-21 03:25 +0000
        Re: Does ANSI C allow free() to always be empty? Richard Damon <Richard@Damon-Family.org> - 2014-03-21 20:58 -0400
          Re: Does ANSI C allow free() to always be empty? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 16:11 -0700
            Re: Does ANSI C allow free() to always be empty? Richard Damon <Richard@Damon-Family.org> - 2014-03-29 22:27 -0400
              Re: Does ANSI C allow free() to always be empty? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-30 13:18 -0700
                Re: Does ANSI C allow free() to always be empty? Richard Damon <Richard@Damon-Family.org> - 2014-03-30 20:49 -0400
                  Re: Does ANSI C allow free() to always be empty? Tim Rentsch <txr@alumni.caltech.edu> - 2014-04-17 10:52 -0700
              Re: Does ANSI C allow free() to always be empty? James Kuyper <jameskuyper@verizon.net> - 2014-03-31 11:18 -0400
      Re: Does ANSI C allow free() to always be empty? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-21 03:31 +0000
      Re: Does ANSI C allow free() to always be empty? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 15:39 -0700
        Re: Does ANSI C allow free() to always be empty? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-30 04:22 +0000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#41634

Frompartremmaps@gmail.com
Date2014-03-11 23:22 -0700
Message-ID<0beb6c0d-1b14-4bdd-b410-d355f8e247c5@googlegroups.com>
In reply to#41607
On Tuesday, March 11, 2014 6:19:18 AM UTC-7, Martin Shobe wrote:
> On 3/10/2014 10:55 PM, partremmaps@gmail.com wrote:
> 

<snip>


> >
> 
> > Could you expound on the "as-if" rule (or reference standard section)?
> 
> 
> 
> Take a look at 5.1.2.3.1, 5.1.2.3.4, and 5.1.2.3.6 in N1570. Part of 
> 
> 5.1.2.3.4 says that side-effects can be omitted if they aren't needed. 
> 
> 5.1.2.3.6 tells you what's needed.
> 
> 
> 
> Martin Shobe


Thanks Martin.

5.1.2.3.1p4 reads:
4   In the abstract machine, all expressions are evaluated as specified by the semantics. An
    actual implementation need not evaluate part of an expression if it can deduce that its
    value is not used and that no needed side effects are produced


There is a difference between saying that the evaluation of an expression may be skipped if the implementation can deduce that there is no need, and saying that it may skip anything if it can't prove the need for it.

It's hard to word.

But let me try again:

The standard says that the evaluation of an expression need not take place IF it can deduce that there's no need. However, by default, if it cannot deduce whether or not there is a need, then it must evaluate the expression.

Thus, if the implementation can deduce that a given call to free() would not free anything, then by all means optimize it out. However, the question is about a case where free() in a hosted environment is passed as an argument a pointed to valid space earlier allocated by malloc().


It would sort of be OK to say that if the implementation could deduce that the current program and no other program would ever need the memory, that it need not be freed.

But, since the implementation cannot know the future of other programs then it seems to me that it must not fail to free memory as described.


It is true that 5.1.2.3.1p6 does not list any memory allocation stuff but it is only a very brief listing of the minimum requirements.

I don't think that's a good argument that free may therefore be empty and neglect to free memory, if we take 5.1.2.3.1p6 to mean that, then would it not also mean that the vast majority of the standard was also not required to be complied with?

For a hosted environment (See 5.1.2.2p1), the implementation "shall conform to the following specifications." And one of those following specifications is the specification of how free() works.

I'm not saying that 5.1.2.3.1p6 is not a requirement, but that it is not the only requirement for a hosted system.




I don't know if I dare try an analogy.

But let's say the boss says "Jesse, go to the back and get box of oranges."
I might say "Sir, I was just back there 30 seconds ago to get Apples and we are out or oranges."

If what I said is true, then that's a fine form of optimization.

However, if I had not been back there recently and did not actually know whether we had more oranges, (Or even if I did know we had more oranges) but if I knew that I had the only key to the back, I could tell the boss that we did not have oranges because I knew he had no way of knowing whether it was true. See the difference?

I am likening the user's program code to the boss, and the implementation to the worker.

There is a difference between knowing that a step can be skipped with no change in outcome, and allowing a change in outcome because it can be hidden from the program.

Or do you really think the standard's authors intended for the standard to not require free() to ever actually free memory, for all practical purposes?

Thanks,

~Jesse

[toc] | [prev] | [next] | [standalone]


#41645

FromMartin Shobe <martin.shobe@yahoo.com>
Date2014-03-12 08:09 -0500
Message-ID<lfpm9v$kiu$1@dont-email.me>
In reply to#41634
On 3/12/2014 1:22 AM, partremmaps@gmail.com wrote:
> On Tuesday, March 11, 2014 6:19:18 AM UTC-7, Martin Shobe wrote:
>> On 3/10/2014 10:55 PM, partremmaps@gmail.com wrote:
>>> Could you expound on the "as-if" rule (or reference standard section)?

>> Take a look at 5.1.2.3.1, 5.1.2.3.4, and 5.1.2.3.6 in N1570. Part of
>>
>> 5.1.2.3.4 says that side-effects can be omitted if they aren't needed.
>>
>> 5.1.2.3.6 tells you what's needed.

> Thanks Martin.

> 5.1.2.3.1p4 reads:
> 4   In the abstract machine, all expressions are evaluated as specified by the semantics. An
>      actual implementation need not evaluate part of an expression if it can deduce that its
>      value is not used and that no needed side effects are produced

I'm going to assume you meant 5.1.2.3p4 (or 5.1.2.3.4 as I put it) here 
instead of 5.1.2.3.1p4 which N1570 doesn't have.

The key phrase here is "needed side effects". So, what exactly are the 
"needed side effect". That is detailed in 5.1.2.3p6.

> There is a difference between saying that the evaluation of an expression may be skipped if the implementation can deduce that there is no need, and saying that it may skip anything if it can't prove the need for it.

That's a straw man. I didn't say it could skip something if it couldn't 
prove a need for it. It is indeed required to prove that the 
side-effects of free() isn't needed for that implementation, and I've 
never disputed that. However, that isn't enough to rule out that free() 
can be implemented as a no-op.

> It's hard to word.
>
> But let me try again:
>
> The standard says that the evaluation of an expression need not take place IF it can deduce that there's no need. However, by default, if it cannot deduce whether or not there is a need, then it must evaluate the expression.

Or something that produces the same observable behavior as that 
expression in the context it appears in.

> Thus, if the implementation can deduce that a given call to free() would not free anything, then by all means optimize it out. However, the question is about a case where free() in a hosted environment is passed as an argument a pointed to valid space earlier allocated by malloc().

> It would sort of be OK to say that if the implementation could deduce that the current program and no other program would ever need the memory, that it need not be freed.

Just the current program, C doesn't place any restrictions at all on how 
more than one program interacts.

> But, since the implementation cannot know the future of other programs then it seems to me that it must not fail to free memory as described.
>
>
> It is true that 5.1.2.3.1p6 does not list any memory allocation stuff but it is only a very brief listing of the minimum requirements.

It's a listing of what behavior must be preserved between the abstract 
machine and the actual implementation.

> I don't think that's a good argument that free may therefore be empty and neglect to free memory, if we take 5.1.2.3.1p6 to mean that, then would it not also mean that the vast majority of the standard was also not required to be complied with?

Compliance is still required, but the standard isn't as strict as you 
seem to think.

> For a hosted environment (See 5.1.2.2p1), the implementation "shall conform to the following specifications." And one of those following specifications is the specification of how free() works.
>
> I'm not saying that 5.1.2.3.1p6 is not a requirement, but that it is not the only requirement for a hosted system.

[snip analogy]

> There is a difference between knowing that a step can be skipped with no change in outcome, and allowing a change in outcome because it can be hidden from the program.
>
> Or do you really think the standard's authors intended for the standard to not require free() to ever actually free memory, for all practical purposes?

Of course not, and I've even said that. However, I've also said that 
it's ok for free() to be implemented as a no-op. Those aren't mutually 
exclusive positions.

Martin Shobe

[toc] | [prev] | [next] | [standalone]


#41657

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-03-12 11:29 -0400
Message-ID<lfpuh1$jmt$1@dont-email.me>
In reply to#41645
On 03/12/2014 09:09 AM, Martin Shobe wrote:
...
> I'm going to assume you meant 5.1.2.3p4 (or 5.1.2.3.4 as I put it) here

That's not a good idea. For example, 5.2.1p2 and 5.2.1.2 refer to two
different things. If you change the 'p' to a '.', you discard the
ability to distinguish between them.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#41547

FromMartin Shobe <martin.shobe@yahoo.com>
Date2014-03-10 07:29 -0500
Message-ID<lfkb76$80o$2@dont-email.me>
In reply to#41509
On 3/9/2014 7:39 AM, Ben Bacarisse wrote:
[snip]
> Thus, in my view, your question all revolves around the extra phrase
> "made available for further allocation".  Must this happen immediately,
> or could the storage be made available some while later?  Could it be
> made available right at the end of the program's execution (when it's
> too late for the program itself)?

I think it must happen as if it had occurred by the time free() returns. 
As far as I can tell, it's just another side-effect. The reason it can 
be delayed is the "as-if" rule.

[snip]

Martin Shobe

[toc] | [prev] | [next] | [standalone]


#41506

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-03-09 09:14 +0000
Message-ID<lfhbdu$jnc$1@speranza.aioe.org>
In reply to#41500
partremmaps@gmail.com wrote:
> According to the ANSI C Standard, may free() be an empty function?
 
> I am not talking about implementations which do not support 
> dynamic memory allocation.
 
(snip)

> I am talking about implementations and architecture which fully 
> support malloc, calloc, and realloc, and the situation where 
> free() has been passed a valid and current pointer to currently 
> allocated space, having been allocated earlier by a successful 
> call by malloc().
 
> A couple of people who are in the daily habit of giving C advice 
> on IRC told me that even in these implementations and situations, 
> free() may be an empty function and do nothing and still be 
> standards compliant.

That would be most obvious for a system with garbage collection.

As well as I know it, the standard leaves actual limits on memory
usage system dependent, and if not done carefully might be 
considered a low "quality of implemenation". 

If one isn't careful with garbage collection, for example with
a circular linked list, one might expect it to be released, but
the GC doesn't release it. 

I don't know if there is a C compiler for IBM System/38, but as
I understand it virtual addresses aren't reused. With 64 bit
virtual addresses (and in years past) that was reasonable.
(It might still be that 64 bit virtual is enough.) 

-- glen

[toc] | [prev] | [next] | [standalone]


#41572

FromRobert Wessel <robertwessel2@yahoo.com>
Date2014-03-10 15:33 -0500
Message-ID<i08sh9luarmcccnnmub27oolag6kfvf31l@4ax.com>
In reply to#41506
On Sun, 9 Mar 2014 09:14:38 +0000 (UTC), glen herrmannsfeldt
<gah@ugcs.caltech.edu> wrote:

>partremmaps@gmail.com wrote:
>> According to the ANSI C Standard, may free() be an empty function?
> 
>> I am not talking about implementations which do not support 
>> dynamic memory allocation.
> 
>(snip)
>
>> I am talking about implementations and architecture which fully 
>> support malloc, calloc, and realloc, and the situation where 
>> free() has been passed a valid and current pointer to currently 
>> allocated space, having been allocated earlier by a successful 
>> call by malloc().
> 
>> A couple of people who are in the daily habit of giving C advice 
>> on IRC told me that even in these implementations and situations, 
>> free() may be an empty function and do nothing and still be 
>> standards compliant.
>
>That would be most obvious for a system with garbage collection.
>
>As well as I know it, the standard leaves actual limits on memory
>usage system dependent, and if not done carefully might be 
>considered a low "quality of implemenation". 
>
>If one isn't careful with garbage collection, for example with
>a circular linked list, one might expect it to be released, but
>the GC doesn't release it. 
>
>I don't know if there is a C compiler for IBM System/38, but as
>I understand it virtual addresses aren't reused. With 64 bit
>virtual addresses (and in years past) that was reasonable.
>(It might still be that 64 bit virtual is enough.) 


There was a C compiler for the AS/400, and it the generated code was
really slow.  Later versions added support to the system for a more
traditional memory architecture, much friendlier to C.

Anyway, the AS/400 (and S/38) basically tagged pointers so (1) the
system could always find them, and (2) an application could not alter
them (a store to a pointer was allowed, but it would clear the tag
bit, hence invalidating the pointer, and setting the tag was a
privileged operation).  Addresses could be reused, but the system
would know when the application no longer had any valid pointers to
that address.  Pointers on that early C implementation were also fat
(16 bytes).

I don't know how some of the exotic things that as possible (writing
the pointer a pointer to a file and reading it back later, encrypting
a pointer, etc.), worked on that implementation.

[toc] | [prev] | [next] | [standalone]


#41535

Frompartremmaps@gmail.com
Date2014-03-09 23:05 -0700
Message-ID<09f7d573-218c-4653-8374-0395e639ae4b@googlegroups.com>
In reply to#41500
On Saturday, March 8, 2014 10:08:24 PM UTC-8, partr...@gmail.com wrote:
> According to the ANSI C Standard, may free() be an empty function?
> 
> 
> 
> I am not talking about implementations which do not support dynamic memory allocation.
> 
> 
> 
> I am also not talking about cases where free() is passed as an argument something other than a current valid pointer earlier returned by a successful call to calloc, malloc, or realloc.
> 
> 
> 
> I am talking about implementations and architecture which fully support malloc, calloc, and realloc, and the situation where free() has been passed a valid and current pointer to currently allocated space, having been allocated earlier by a successful call by malloc().
> 
> 

<snip>

I just had a thought on the topic.

It's too bad the standard authors didn't put one of the following statements in the standard. If they had, then the question would be answered one way or the other:

Proposed statement 1:
Any missing or unclear technical detail in the standard, even if so small it may have been over looked by the maintainers, may be used to render meaningless any sections of the standard even if said sections contain clear and verbose wording on the topic.

Proposed statement 2:
In the case of a question of a technicality where there are no notes to clarify, the meaning of the standard should be taken as it written keeping in mind the purpose of what is written.

If it had one of those statements, which would it be?

The fact is that the standard says that free is to free the space pointed to, making it available to further allocation. It doesn't spell out that it has to happen right away or that it may do it later, but then again it doesn't spell out that all of the other functions have to do theirs right away either.

However, it does fully support the concept that side effects happen and finish within sequence points.

The technicality is that the standard says that modifying an object is a side effect, but it doesn't say that deleting an object is a side effect, and free deletes an object.

However, malloc creates an object. But we certainly can't argue that malloc is allowed to create that object later - it must be ready BEFORE the ending sequence point for malloc() because otherwise the next statement might try to use unallocated memory.

And even free() is to free space for further allocation -- what if the very next statement was to allocate memory, and that it needed the just freed memory? The purpose of the standard's wording is clear: free the memory so it can be re allocated. Period.

To me, it seems that creating and deleting objects would also have to be considered of the same type of thing. Obviously, creating an object with malloc() must happen before malloc()'s last sequence point, so I see no reason to say that deleting an object with free() would be any different.

It does not make sense to me to make any assumption on lack of details that renders useless clearly worded sections of the standard.

The standard says that free does certain things. If it does not do those things in a given implementation, then it sure seems like it's not standard to me.

Thanks,

Jesse

[toc] | [prev] | [next] | [standalone]


#41548

FromMartin Shobe <martin.shobe@yahoo.com>
Date2014-03-10 07:43 -0500
Message-ID<lfkc18$eim$1@dont-email.me>
In reply to#41535
On 3/10/2014 1:05 AM, partremmaps@gmail.com wrote:
> On Saturday, March 8, 2014 10:08:24 PM UTC-8, partr...@gmail.com wrote:
[snip]
> The fact is that the standard says that free is to free the space pointed to, making it available to further allocation. It doesn't spell out that it has to happen right away or that it may do it later, but then again it doesn't spell out that all of the other functions have to do theirs right away either.
>
> However, it does fully support the concept that side effects happen and finish within sequence points.
>
> The technicality is that the standard says that modifying an object is a side effect, but it doesn't say that deleting an object is a side effect, and free deletes an object.
>
> However, malloc creates an object. But we certainly can't argue that malloc is allowed to create that object later - it must be ready BEFORE the ending sequence point for malloc() because otherwise the next statement might try to use unallocated memory.
>
> And even free() is to free space for further allocation -- what if the very next statement was to allocate memory, and that it needed the just freed memory? The purpose of the standard's wording is clear: free the memory so it can be re allocated. Period.
>
> To me, it seems that creating and deleting objects would also have to be considered of the same type of thing. Obviously, creating an object with malloc() must happen before malloc()'s last sequence point, so I see no reason to say that deleting an object with free() would be any different.
>
> It does not make sense to me to make any assumption on lack of details that renders useless clearly worded sections of the standard.
>
> The standard says that free does certain things. If it does not do those things in a given implementation, then it sure seems like it's not standard to me.

I don't think the question is, "Can free() not deallocate the memory." 
It clearly must. The question is, "Can free() be implemented as a 
no-op." Here, the answer is clearly "yes, as long as it works as if it 
had deallocated the memory." If that deallocation doesn't result in a 
requirement that a future malloc(), et. al., succeed, then the "real" 
deallocation can be put off indefinitely via the "as-if" rule.

Martin Shobe

[toc] | [prev] | [next] | [standalone]


#41554

Fromgordonb.3qcze@burditt.org (Gordon Burditt)
Date2014-03-10 12:05 -0500
Message-ID<p46dnTWRK9RpbYDOnZ2dnUVZ_rKdnZ2d@posted.internetamerica>
In reply to#41548
> I don't think the question is, "Can free() not deallocate the memory." 
> It clearly must. The question is, "Can free() be implemented as a 
> no-op." Here, the answer is clearly "yes, as long as it works as if it 
> had deallocated the memory." If that deallocation doesn't result in a 
> requirement that a future malloc(), et. al., succeed, then the "real" 
> deallocation can be put off indefinitely via the "as-if" rule.

Ok, put another way:  Can the following program ever return
EXIT_FAILURE at Line B when run in a hosted environment?

#include <stdlib.h>

int main(int argc, char **argv)
{
	char	*p;

	p = malloc(1);
	if (p == NULL)
	{
		/* dummy malloc() implementation */
		return EXIT_SUCCESS;	/* Line A */
	}
	while (1)
	{
		free(p);
		p = malloc(1);
		if (p == NULL) 
		{
			return EXIT_FAILURE;	/* Line B */
		}
	}
	/* not reached */
}

Notes:  if malloc() is a dummy implementation that always returns
NULL, then it will return EXIT_SUCCESS at Line A.  The maximum
amount of dynamic memory that this program requires is 1 byte, plus
any alignment and bookkeeping overhead.

This program with a functioning free() and/or garbage collection
that actually collects garbage will run forever.  This is the
simplest case for garbage collection:  no linked lists, pointers
stuck in global variables, pointers stuck in files, etc.

You may consider the test over when the number of calls to malloc()
exceeds the sum of the number of bits in processor memory, cache,
registers, page space, and swap space.  Unfortunately, there's no
guarantee that this count can fit in a uintmax_t, so I didn't put
in a counter.

[toc] | [prev] | [next] | [standalone]


#41586

Frompartremmaps@gmail.com
Date2014-03-10 20:16 -0700
Message-ID<64f87c65-b9b1-4e7b-b3ac-3cbc557cb133@googlegroups.com>
In reply to#41554
On Monday, March 10, 2014 10:05:56 AM UTC-7, Gordon Burditt wrote:
> > I don't think the question is, "Can free() not deallocate the memory."
>
> > It clearly must. The question is, "Can free() be implemented as a
>
> > no-op." Here, the answer is clearly "yes, as long as it works as if it
>
> > had deallocated the memory." If that deallocation doesn't result in a
>
> > requirement that a future malloc(), et. al., succeed, then the "real"
>
> > deallocation can be put off indefinitely via the "as-if" rule.
>
>
>
> Ok, put another way:  Can the following program ever return
>
> EXIT_FAILURE at Line B when run in a hosted environment?
>
>
>
> #include <stdlib.h>
>
>
>
> int main(int argc, char **argv)
>
> {
>
>     char    *p;
>
>
>
>     p = malloc(1);
>
>     if (p == NULL)
>
>     {
>
>         /* dummy malloc() implementation */
>
>         return EXIT_SUCCESS;    /* Line A */
>
>     }
>
>     while (1)
>
>     {
>
>         free(p);
>
>         p = malloc(1);
>
>         if (p == NULL)
>
>         {
>
>             return EXIT_FAILURE;    /* Line B */
>
>         }
>
>     }
>
>     /* not reached */
>
> }
>
>
>
> Notes:  if malloc() is a dummy implementation that always returns
>
> NULL, then it will return EXIT_SUCCESS at Line A.  The maximum
>
> amount of dynamic memory that this program requires is 1 byte, plus
>
> any alignment and bookkeeping overhead.
>
>
>
> This program with a functioning free() and/or garbage collection
>
> that actually collects garbage will run forever.  This is the
>
> simplest case for garbage collection:  no linked lists, pointers
>
> stuck in global variables, pointers stuck in files, etc.
>
>
>
> You may consider the test over when the number of calls to malloc()
>
> exceeds the sum of the number of bits in processor memory, cache,
>
> registers, page space, and swap space.  Unfortunately, there's no
>
> guarantee that this count can fit in a uintmax_t, so I didn't put
>
> in a counter.


I like your sample program. As to wheather malloc() and friends are allowed (in a hosted environment) to simply return NULL without attempting to allocate, the standard does clearly describe them as allocating or returning NULL if the cannot allocate. (See [Memory management functions])

For realloc it actually uses the phrase "If memory for the new object cannot be allocated,..." and "...., or a null pointer if the new object could not be allocated."

So while the standard does not lay out the rules for how hard malloc must try, there is no question that it must try.

Your program (above) could return EXIT_FAILURE at Line B if another program in the hosted environment allocated the last byte, or for example if another program had allocated a billion 1-byte objects and the dynamic memory management system could only deal with a billion allocated objects, so it could fail at B even with ram left over.

But the point is that it tried.


Thanks,

~Jesse

[toc] | [prev] | [next] | [standalone]


#42332

FromTim Rentsch <txr@alumni.caltech.edu>
Date2014-03-29 16:27 -0700
Message-ID<kfn4n2gk2kk.fsf@x-alumni2.alumni.caltech.edu>
In reply to#41554
gordonb.3qcze@burditt.org (Gordon Burditt) writes:

>> I don't think the question is, "Can free() not deallocate the memory." 
>> It clearly must. The question is, "Can free() be implemented as a 
>> no-op." Here, the answer is clearly "yes, as long as it works as if it 
>> had deallocated the memory." If that deallocation doesn't result in a 
>> requirement that a future malloc(), et. al., succeed, then the "real" 
>> deallocation can be put off indefinitely via the "as-if" rule.
>
> Ok, put another way:  Can the following program ever return
> EXIT_FAILURE at Line B when run in a hosted environment?
>
> #include <stdlib.h>
>
> int main(int argc, char **argv)
> {
> 	char	*p;
>
> 	p = malloc(1);
> 	if (p == NULL)
> 	{
> 		/* dummy malloc() implementation */
> 		return EXIT_SUCCESS;	/* Line A */
> 	}
> 	while (1)
> 	{
> 		free(p);
> 		p = malloc(1);
> 		if (p == NULL) 
> 		{
> 			return EXIT_FAILURE;	/* Line B */
> 		}
> 	}
> 	/* not reached */
> }
>
> Notes:  if malloc() is a dummy implementation that always returns
> NULL, then it will return EXIT_SUCCESS at Line A.  The maximum
> amount of dynamic memory that this program requires is 1 byte, plus
> any alignment and bookkeeping overhead.

Very nice way of phrasing the question.  The answer is YES, the
return at point B may conformingly occur.  The Standard imposes
no requirements on when an attempted allocation must, or if ever,
succeed.  Since there are no circumstances under which a call to
malloc() is required to succeed, it may fail at any time and
still be conforming.

[toc] | [prev] | [next] | [standalone]


#41594

Frompartremmaps@gmail.com
Date2014-03-10 21:48 -0700
Message-ID<47d235ee-980c-4df8-94fa-d1121c6998ba@googlegroups.com>
In reply to#41548
On Monday, March 10, 2014 5:43:18 AM UTC-7, Martin Shobe wrote:

<snip>

>
>
> I don't think the question is, "Can free() not deallocate the memory."
>
> It clearly must. The question is, "Can free() be implemented as a
>
> no-op." Here, the answer is clearly "yes, as long as it works as if it
>
> had deallocated the memory." If that deallocation doesn't result in a
>
> requirement that a future malloc(), et. al., succeed, then the "real"
>
> deallocation can be put off indefinitely via the "as-if" rule.
>
>
>
> Martin Shobe



So I guess one could say that all standard C functions are allowed to perform no function so long as their described functionality gets executed within said function's sequence points.
or "No function needs to actually do anything so long as for all practical purposes it behaves as described..."

But, the question that I am asking is whether free is allowed to not deallocate memory. The person who prompted me to ask this question in the first place claimed that because the program in question could not, using only the semantics of the C Abstract machine, determine whether free() had done anything, and therefore, free() need not do anything, even if it meant a massive memory leak on a program which did appropriately call free() for all memory it allocated.

I have two issues with saying that deallocation can be delayed. One is that the standard says that all side effects must be completed before the last sequence point of a full expression.
Thus, for the side effect of free to be delayed seems outside of the standard.

Secondly, the standard does say that free() makes the space available for further allocation. However, if the implementation for example delayed freeing until it ran out of memory then freed on demand, (Android style LOL) then, for all practical purposes, all calls to free() would have the same effect as if free had fully freed within its own sequence points.

However, I do not see the letter or the spirit of the standard allowing free() to have a delayed effect. Obviously, malloc() is not allowed to postpone its creation of an object otherwise immediate use of that object would be bad. allocating and deallocating are the same class of side effects.

Thanks,

~Jesse

[toc] | [prev] | [next] | [standalone]


#41595

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-03-11 05:52 +0000
Message-ID<lfm8b0$4cs$1@speranza.aioe.org>
In reply to#41594
partremmaps@gmail.com wrote:
> On Monday, March 10, 2014 5:43:18 AM UTC-7, Martin Shobe wrote:

(snip)
>> I don't think the question is, "Can free() not deallocate the memory."
>> It clearly must. The question is, "Can free() be implemented as a
>> no-op." 

(snip)

> But, the question that I am asking is whether free is allowed to 
> not deallocate memory. The person who prompted me to ask this 
> question in the first place claimed that because the program in 
> question could not, using only the semantics of the C Abstract 
> machine, determine whether free() had done anything, and therefore, 
> free() need not do anything, even if it meant a massive memory 
> leak on a program which did appropriately call free() for all 
> memory it allocated.

and the standard leaves the amount of available memory up to the
implementation, and often on whatever else the machine is doing
at the time.
 
> I have two issues with saying that deallocation can be delayed. 
> One is that the standard says that all side effects must be 
> completed before the last sequence point of a full expression.
> Thus, for the side effect of free to be delayed seems outside 
> of the standard.

As far as I know, that is for side effects visible to the program.

Note that printf() has the side effect of printing something somewhere,
such as a terminal or line printer, but that effect usually happens
much later, if ever. 
 
> Secondly, the standard does say that free() makes the space 
> available for further allocation. However, if the implementation 
> for example delayed freeing until it ran out of memory then freed 
> on demand, (Android style LOL) then, for all practical purposes, 
> all calls to free() would have the same effect as if free had 
> fully freed within its own sequence points.
 
> However, I do not see the letter or the spirit of the standard 
> allowing free() to have a delayed effect. Obviously, malloc() is 
> not allowed to postpone its creation of an object otherwise 
> immediate use of that object would be bad. 

Seems that many systems now have lazy allocation, also known as
overcommit, where malloc() never returns NULL. Similar to the way
airlines overbook expecting some no-shows, lazy allocation assumes
that you malloc() more than you really need. 

> allocating and deallocating are the same class of side effects.

On many systems, the available memory depends on what other programs
are using, so the side effects of malloc() and free() are, to some
extent, outside the control of the program. Seems to me that makes
them different.

-- glen

[toc] | [prev] | [next] | [standalone]


#42026

Frompartremmaps@gmail.com
Date2014-03-20 19:14 -0700
Message-ID<20ce79fa-cd1b-4f0b-9917-f68300602f80@googlegroups.com>
In reply to#41500
On Saturday, March 8, 2014 10:08:24 PM UTC-8, partr...@gmail.com wrote:
> According to the ANSI C Standard, may free() be an empty function?
>


<snip>


>
> Their reasoning is thus:
>
>
>
> "Because the C program cannot, using only semantics of the C Abstract Machine, determine that free() did nothing, it is therefore compliant for free() to do nothing even though it was passed a pointer to valid allocated space having earlier been allocated by malloc()."
>
>
>
> and
>
>
>
> "On a system where malloc and free are fully supported by hardware and software, free() still may be void and empty and always do nothing while still being ANSI C compliant because free() never has  a measurable effect, so nothing need be done to produce a measurable effect."
>
>


<snip>



This discussion has been most fascinating to me because I sort of expected that several thinking people would look at the same evidence (the written standard) and come to pretty close the same conclusion.

My desire for some level of agreement is that as long as we seem to disagree  it means some of us don't understand the topic, and chances are that it's me since by far I'm sure you're all smarter than I. However, I'm trying my very best to understand the standard and it generally makes sense, and yet the conclusion I arrive at seems different.

Putting aside technical wording traps,

Do we at least agree that it is most likely that the standard authors did fully intend (for a hosted environment) for malloc() and friends to allocate if they can, and for free() to free the pointed to memory further allocation?

One of you did make reference to the phrase "language lawyer" which did get me to thinking: In a court of law, it is not uncommon for a lawyer to bear heavily on some fine technical detail or specific word or even the absents of a specific word the law in order to construe the law in such a way that any commoner would see as the exact opposite of what the law was actually intended to cover, and even contrary to the bulk of the wording of the law.

But I don't see why anyone would be motivated to do that with the C standard - it's not like someone goes to jail on a technical reading of C11!
*bang bang* "I hereby find the accused guilty of allocating more memory than was available and sentence him to 30 seconds of trying to use swapspace for ram..."


Anyway, I can't really think of any particular answer to this perplexing question so shall probably soon cease from bothering ya'll.
(I obviously may respond further - but I just don't see there being much more to say on the topic.)


But do let me sincerely thank you for trying to help me understand!


~Jesse


PS: I would have posted this sooner but my newsreader was having issues.

[toc] | [prev] | [next] | [standalone]


#42028

FromKaz Kylheku <kaz@kylheku.com>
Date2014-03-21 03:25 +0000
Message-ID<20140320201354.407@kylheku.com>
In reply to#42026
On 2014-03-21, partremmaps@gmail.com <partremmaps@gmail.com> wrote:
> My desire for some level of agreement is that as long as we seem to disagree
> it means some of us don't understand the topic, and chances are that it's me
> since by far I'm sure you're all smarter than I. However, I'm trying my very
> best to understand the standard and it generally makes sense, and yet the
> conclusion I arrive at seems different.

It is not enough to understand the standrad, but to understand what and who the
standard is for and how it can be put to use.

The standard is ideally suited to one thing: describing the behavior of features.

The standard is less suited to dictating what is actually present or not.

If a free function does nothing, it's basically a matter of word semantics
whether that situation is a case of something missing or a something deviating
from specified behavior.

Users and implementors can negotiate with each other that it is okay not to
have a fully working free function.

People can take the standard and customize it how they see fit, to interpret
how they see fit and and also to prioritize the requirements.

> Putting aside technical wording traps,
>
> Do we at least agree that it is most likely that the standard authors did
> fully intend (for a hosted environment) for malloc() and friends to allocate
> if they can, and for free() to free the pointed to memory further allocation?

This is obviously what the function is for.

For instance, it would probaby not be acceptable for free to be implemented,
but to have some side effect which is completely different from freeing memory
that came from {ma,ca,re}alloc.  Like, say, closing all stdio streams.

Doing such things would interfere with some correct programs which call free in
a proper way.

Even if some implementors duck out of implementing free, and their users
accept that, the standard's job remains giving a description of free when
it is implemented in earnest.

[toc] | [prev] | [next] | [standalone]


#42050

FromRichard Damon <Richard@Damon-Family.org>
Date2014-03-21 20:58 -0400
Message-ID<Je5Xu.3871$IN1.2467@en-nntp-15.dc1.easynews.com>
In reply to#42028
It has been interesting reading the arguments here about what free can
or can not do. Thinking about it, I realize that the C standard has no
power, in and of itself, to force free to do anything, or even make any
program do anything. If I write a C compiler, and if it fails to issue a
required diagnostic, or write a C program that dereferences a NULL
pointer, no one from the standard committee or ISO is going to show up
to take away my programming license or arrest me and send me to the
dilithium mines. The C standard just isn't that kind of standard.

What the C standard does do, is provide a definition (actually a number
of them), so that people can talk about C programing and have something
solid in agreement. For example, if you are hiring a programmer to write
a program, you can write specification based on the standard. This also
means that in most places, to advertise that you implementation meets
the C standard, when it doesn't could get you into trouble for false
advertising.

My feeling is that based on this, if an vendor provided an
implementation that claimed to conform to the C standard, and in the
implementation free was always vacuous (and provided no other way in
background to recover the memory), it would probably be found guilty of
false advertising as the standard does say that free will make the
memory available for future allocations.

On the other hand, I can easily see (and in fact have seen), an
implementation providing several version of the heap functions, one (or
more) of which were empty. Thus is you have an application that is only
going to malloc memory, and will never free it (perhaps initially
allocating some needed buffers, and after that memory usage is
effectively constant), a heap system to support this can be a more
efficient in memory usage (since it doesn't need to save information to
support deallocation). This is great if it also provides a full
functioning version for programs that need that ability.

[toc] | [prev] | [next] | [standalone]


#42331

FromTim Rentsch <txr@alumni.caltech.edu>
Date2014-03-29 16:11 -0700
Message-ID<kfn8ursk3c3.fsf@x-alumni2.alumni.caltech.edu>
In reply to#42050
Richard Damon <Richard@Damon-Family.org> writes:

> It has been interesting reading the arguments here about what free
> can or can not do.  Thinking about it, I realize that the C
> standard has no power, in and of itself, to force free to do
> anything, or even make any program do anything.  If I write a C
> compiler, and if it fails to issue a required diagnostic, or write
> a C program that dereferences a NULL pointer, no one from the
> standard committee or ISO is going to show up to take away my
> programming license or arrest me and send me to the dilithium
> mines.  The C standard just isn't that kind of standard.
>
> What the C standard does do, is provide a definition (actually a
> number of them), so that people can talk about C programing and
> have something solid in agreement.  For example, if you are hiring
> a programmer to write a program, you can write specification based
> on the standard.  This also means that in most places, to
> advertise that you implementation meets the C standard, when it
> doesn't could get you into trouble for false advertising.
>
> My feeling is that based on this, if an vendor provided an
> implementation that claimed to conform to the C standard, and in
> the implementation free was always vacuous (and provided no other
> way in background to recover the memory), it would probably be
> found guilty of false advertising as the standard does say that
> free will make the memory available for future allocations.

An attorney arguing that point of view would have a significant
uphill battle.  Section 5.1.2.3 p6 spells out pretty clearly what
the bar is for being a conforming implementation, and it depends
only on externally observable behavior, not on any implementation
internal details.  Moreover if any member of the WG14 committee
were called to offer expert testimony in the case, I'm confident
their testimony would be that such questions are concerned only
with quality of implementation, and so are deliberately outside
of what the Standard considers in defining conformance.

[toc] | [prev] | [next] | [standalone]


#42342

FromRichard Damon <Richard@Damon-Family.org>
Date2014-03-29 22:27 -0400
Message-ID<aiLZu.19517$S85.19010@en-nntp-16.dc1.easynews.com>
In reply to#42331
On 3/29/14, 7:11 PM, Tim Rentsch wrote:
> Richard Damon <Richard@Damon-Family.org> writes:
>> My feeling is that based on this, if an vendor provided an
>> implementation that claimed to conform to the C standard, and in
>> the implementation free was always vacuous (and provided no other
>> way in background to recover the memory), it would probably be
>> found guilty of false advertising as the standard does say that
>> free will make the memory available for future allocations.
> 
> An attorney arguing that point of view would have a significant
> uphill battle.  Section 5.1.2.3 p6 spells out pretty clearly what
> the bar is for being a conforming implementation, and it depends
> only on externally observable behavior, not on any implementation
> internal details.  Moreover if any member of the WG14 committee
> were called to offer expert testimony in the case, I'm confident
> their testimony would be that such questions are concerned only
> with quality of implementation, and so are deliberately outside
> of what the Standard considers in defining conformance.
> 

Actually, since that clause specifies that the output be correct
according to what the abstract semantics would have produced, and the
definition of free is to make the memory available for further
allocations, this clause can NOT be used to excuse a reasonable reading
to require free to at least attempt something.

As to being merely quality of implementations, most jurisdictions have
laws that require products to have at least certain very minimal levels
of quality to be offered.

After all, would YOU allow someone to say the following is a C compiler:
a shell script that checked if a file matches a specific sample, if it
matches copy another file to a specified place, and if not print a message?

By a strict reading of the standard, such a script (with appropriate
documentation) seems to meet all that the standard requires. After all,
5.2.4.1 only requires the ability to execute "at least one program ...",
and may (because there is no other requirement) indicate that any other
program for any reason doesn't meet the translation limits. There is a
footnote (non-normative) to avoid fixed limits whenever possible, but
that is 1) not normative, and 2) doesn't actually require anything.

Thus, you may perhaps be able to claim that you conform to the C
standard (quoting a specific standard number), but to call it also a "C
Compiler" may well impose some "higher" standards (namely that it at
least sort of does what it says it does).

[toc] | [prev] | [next] | [standalone]


#42364

FromTim Rentsch <txr@alumni.caltech.edu>
Date2014-03-30 13:18 -0700
Message-ID<kfnr45jh23r.fsf@x-alumni2.alumni.caltech.edu>
In reply to#42342
Richard Damon <Richard@Damon-Family.org> writes:

> On 3/29/14, 7:11 PM, Tim Rentsch wrote:
>> Richard Damon <Richard@Damon-Family.org> writes:
>>> My feeling is that based on this, if an vendor provided an
>>> implementation that claimed to conform to the C standard, and in
>>> the implementation free was always vacuous (and provided no other
>>> way in background to recover the memory), it would probably be
>>> found guilty of false advertising as the standard does say that
>>> free will make the memory available for future allocations.
>> 
>> An attorney arguing that point of view would have a significant
>> uphill battle.  Section 5.1.2.3 p6 spells out pretty clearly what
>> the bar is for being a conforming implementation, and it depends
>> only on externally observable behavior, not on any implementation
>> internal details.  Moreover if any member of the WG14 committee
>> were called to offer expert testimony in the case, I'm confident
>> their testimony would be that such questions are concerned only
>> with quality of implementation, and so are deliberately outside
>> of what the Standard considers in defining conformance.
>
> Actually, since that clause specifies that the output be correct
> according to what the abstract semantics would have produced, and
> the definition of free is to make the memory available for further
> allocations, this clause can NOT be used to excuse a reasonable
> reading to require free to at least attempt something.

The key point is that whether an implementation is conforming
depends only on its behavior.  If we have two implementations
that exhibit the same behavior, then if one is conforming the
other is also, regardless of how they are coded.  It's easy to
sketch out an implementation that obviously does try to conform
to the spirit of the free()/malloc() descriptions, and be
conforming otherwise, yet would exhibit the same behavior as an
implementation with an empty free() body.  Because conformance is
determined solely by behavior, we can't say one is conforming and
the other isn't - either both are or neither is.  Do you mean to
say that the Standard requires malloc() must succeed under some
circumstances?  If so then which portions of the Standard provide
such requirement?  If not then the "sincere" implementation is
conforming and so must also the "insincere" implementation be.

> As to being merely quality of implementations, most jurisdictions
> have laws that require products to have at least certain very
> minimal levels of quality to be offered.

I won't disagree, but that doesn't have anything to do with
the question of false advertising as regards being a conforming
implementation.

> After all, would YOU allow someone to say the following is a C
> compiler:  a shell script that checked if a file matches a
> specific sample, if it matches copy another file to a specified
> place, and if not print a message?
>
> By a strict reading of the standard, such a script (with
> appropriate documentation) seems to meet all that the standard
> requires.  After all, 5.2.4.1 only requires the ability to execute
> "at least one program ...", and may (because there is no other
> requirement) indicate that any other program for any reason
> doesn't meet the translation limits.  There is a footnote
> (non-normative) to avoid fixed limits whenever possible, but that
> is 1) not normative, and 2) doesn't actually require anything.

Your analysis is incomplete.  There are two other significant
requirements of a conforming implementation, namely, it must
"accept" any strictly conforming program, and it must "reject" any
program with a (non-skipped) #error directive.  These additional
requirements actually raise the bar quite a bit, and it isn't
nearly so easy to provide a conforming implementation as the
script outlined above.  However let me ignore those details and
respond to your question as if that didn't matter.

If someone provided such an (extremely limited) implementation, and
claimed it was a conforming implementation, which is the question
under discussion, I would /agree/ that it is conforming.  The
reason I would agree is that I believe this is what the authors
of the Standard intented.  This point is discussed at some length
in the Rationale document.  The authors are fully aware that such
contrivances are possible, yet still chose to define conformance
as they did, knowing full well that the definition adopted allows
such subterfuges.  I believe it is appropriate to take the word
conforming to mean what is both stated and intended by the authors
as its meaning;  to do otherwise would go against both the letter
and the spirit of what the Standard embodies.

> Thus, you may perhaps be able to claim that you conform to the C
> standard (quoting a specific standard number), but to call it also
> a "C Compiler" may well impose some "higher" standards (namely
> that it at least sort of does what it says it does).

The question of whether such an implementation is conforming
is exactly the question under discussion.  That comes straight
out of your posting at the start of this subthread (and still
appearing in the quoted portion above).

[toc] | [prev] | [next] | [standalone]


#42370

FromRichard Damon <Richard@Damon-Family.org>
Date2014-03-30 20:49 -0400
Message-ID<uY2_u.31001$Wy2.15787@en-nntp-16.dc1.easynews.com>
In reply to#42364
On 3/30/14, 4:18 PM, Tim Rentsch wrote:
> Richard Damon <Richard@Damon-Family.org> writes:
> 
>> On 3/29/14, 7:11 PM, Tim Rentsch wrote:
>>> Richard Damon <Richard@Damon-Family.org> writes:
>>>> My feeling is that based on this, if an vendor provided an
>>>> implementation that claimed to conform to the C standard, and in
>>>> the implementation free was always vacuous (and provided no other
>>>> way in background to recover the memory), it would probably be
>>>> found guilty of false advertising as the standard does say that
>>>> free will make the memory available for future allocations.
>>>
>>> An attorney arguing that point of view would have a significant
>>> uphill battle.  Section 5.1.2.3 p6 spells out pretty clearly what
>>> the bar is for being a conforming implementation, and it depends
>>> only on externally observable behavior, not on any implementation
>>> internal details.  Moreover if any member of the WG14 committee
>>> were called to offer expert testimony in the case, I'm confident
>>> their testimony would be that such questions are concerned only
>>> with quality of implementation, and so are deliberately outside
>>> of what the Standard considers in defining conformance.
>>
>> Actually, since that clause specifies that the output be correct
>> according to what the abstract semantics would have produced, and
>> the definition of free is to make the memory available for further
>> allocations, this clause can NOT be used to excuse a reasonable
>> reading to require free to at least attempt something.
> 
> The key point is that whether an implementation is conforming
> depends only on its behavior.  If we have two implementations
> that exhibit the same behavior, then if one is conforming the
> other is also, regardless of how they are coded.  It's easy to
> sketch out an implementation that obviously does try to conform
> to the spirit of the free()/malloc() descriptions, and be
> conforming otherwise, yet would exhibit the same behavior as an
> implementation with an empty free() body.  Because conformance is
> determined solely by behavior, we can't say one is conforming and
> the other isn't - either both are or neither is.  Do you mean to
> say that the Standard requires malloc() must succeed under some
> circumstances?  If so then which portions of the Standard provide
> such requirement?  If not then the "sincere" implementation is
> conforming and so must also the "insincere" implementation be.
> 
First, this statement is false, because an important part of the
equation that needs to be considered is the documentation for the
implementation, it is quite possible for two implementation to behave
identically and one to conform and one to not, because one might
document implementation differently.

The definition of /observable behavior/ refers back to the abstract
machine, and says, in essence, that observable outputs must match that
of the abstract machine, so it is allowed to do things differently in
the real machine than the abstract machine, as long as we can't "see"
the difference on the outside.

Note that the memory allocation function, are defined at the abstract
machine level to allocated memory or null if it CANNOT be allocated.
This would imply that the implementation needs to actually attempt to
return the requested block, so an implementation that returns a null
when it could return a request block has failed to meet a requirement of
the standard. It doesn't matter if the program can detect that it could
have.

Another problem with looking at behavior (at least as a black box) is
that it is impossible to prove conformance. A conforming implementation
has required behavior on every possible conforming program, with every
possible input. As this is an infinite job, it will take an infinite
time. Also, some parts of observable behavior might not be really
observable in practice. For instance, the standard requires that ALL
volatile objects be accessed in accordance to the virtual machine,
including those in "normal" memory. On many machines, this is impossible
to do. Also, some behavior is allowed in the case of "failure", and
(unless you want to allow to arbitrary fail on any or every case), it is
often impossible for the program to determine that something really
failed, and it could be claimed that for an implementation to call
something a failure, when there really wasn't a failure, is a deviation
from the abstract machine, and thus a non-conformity.

This says that conformance determination MUST be "White Box", where we
can look at how it does things, so we can abstractly determine what will
happen in the infinitely large case. This says that we CAN know internal
details about if a failure really did happen or not,and thus insincerity
(declaring a failure when there wasn't) is possible.

>> As to being merely quality of implementations, most jurisdictions
>> have laws that require products to have at least certain very
>> minimal levels of quality to be offered.
> 
> I won't disagree, but that doesn't have anything to do with
> the question of false advertising as regards being a conforming
> implementation.
> 
>> After all, would YOU allow someone to say the following is a C
>> compiler:  a shell script that checked if a file matches a
>> specific sample, if it matches copy another file to a specified
>> place, and if not print a message?
>>
>> By a strict reading of the standard, such a script (with
>> appropriate documentation) seems to meet all that the standard
>> requires.  After all, 5.2.4.1 only requires the ability to execute
>> "at least one program ...", and may (because there is no other
>> requirement) indicate that any other program for any reason
>> doesn't meet the translation limits.  There is a footnote
>> (non-normative) to avoid fixed limits whenever possible, but that
>> is 1) not normative, and 2) doesn't actually require anything.
> 
> Your analysis is incomplete.  There are two other significant
> requirements of a conforming implementation, namely, it must
> "accept" any strictly conforming program, and it must "reject" any
> program with a (non-skipped) #error directive.  These additional
> requirements actually raise the bar quite a bit, and it isn't
> nearly so easy to provide a conforming implementation as the
> script outlined above.  However let me ignore those details and
> respond to your question as if that didn't matter.
> 
The problem with that distinction is that then I suspect that NO
implementation is conforming, as, if you can't stop based on
implementation limits, it is possible to create an arbitrary large
program that must be parsed to determine if a #error is skipped or not.

Since we MUST allow an implementation to declare a translation limit
before the accept/reject decision (or our set of conforming
implementations is empty), the script passes just as well as Clang or
GCC (maybe even better,as it is much less likely to have a bug causing
it to make the wrong determination, or accept and then miss-translate a
program).

> If someone provided such an (extremely limited) implementation, and
> claimed it was a conforming implementation, which is the question
> under discussion, I would /agree/ that it is conforming.  The
> reason I would agree is that I believe this is what the authors
> of the Standard intented.  This point is discussed at some length
> in the Rationale document.  The authors are fully aware that such
> contrivances are possible, yet still chose to define conformance
> as they did, knowing full well that the definition adopted allows
> such subterfuges.  I believe it is appropriate to take the word
> conforming to mean what is both stated and intended by the authors
> as its meaning;  to do otherwise would go against both the letter
> and the spirit of what the Standard embodies.
> 
>> Thus, you may perhaps be able to claim that you conform to the C
>> standard (quoting a specific standard number), but to call it also
>> a "C Compiler" may well impose some "higher" standards (namely
>> that it at least sort of does what it says it does).
> 
> The question of whether such an implementation is conforming
> is exactly the question under discussion.  That comes straight
> out of your posting at the start of this subthread (and still
> appearing in the quoted portion above).
> 

Note, the message I replied to brought up the concept of a court of law
and a "language lawyer", so I suspect that the script implementation
could be found guilty of not being a conforming C compiler, not be cause
it isn't conforming, but because it isn't a C compiler in the first
place (so conformance doesn't really matter).

In the case of free, (and a number of other functions), the standard
provides a (crude) description of the behavior of the abstract machine.
 It says what the function should attempt to do, while allowing it to
fail, for unspecified reasons. I would claim that an implementation that
gratuitously fails has not met the requirements of the abstract machine,
and thus has hit non-conformance. An environment might not provide for a
heap, and thus an implementation might be able to legitimately have a
malloc() that always returns NULL and be conforming. Once the
implementation admits that malloc() can in fact allocate some memory,
free is described as returning that memory for the possibility of
further allocation, so to not do this is non-conforming.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web