Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #41500 > unrolled thread
| Started by | partremmaps@gmail.com |
|---|---|
| First post | 2014-03-08 22:08 -0800 |
| Last post | 2014-03-30 04:22 +0000 |
| Articles | 20 on this page of 45 — 14 participants |
Back to article view | Back to comp.lang.c
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 →
| From | partremmaps@gmail.com |
|---|---|
| Date | 2014-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]
| From | Martin Shobe <martin.shobe@yahoo.com> |
|---|---|
| Date | 2014-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-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]
| From | Martin Shobe <martin.shobe@yahoo.com> |
|---|---|
| Date | 2014-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]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2014-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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2014-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]
| From | partremmaps@gmail.com |
|---|---|
| Date | 2014-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]
| From | Martin Shobe <martin.shobe@yahoo.com> |
|---|---|
| Date | 2014-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]
| From | gordonb.3qcze@burditt.org (Gordon Burditt) |
|---|---|
| Date | 2014-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]
| From | partremmaps@gmail.com |
|---|---|
| Date | 2014-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2014-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]
| From | partremmaps@gmail.com |
|---|---|
| Date | 2014-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]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2014-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]
| From | partremmaps@gmail.com |
|---|---|
| Date | 2014-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2014-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2014-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2014-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2014-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2014-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