Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reverting realloc(non-null, 0)

6 views
Skip to first unread message

Hallvard B Furuseth

unread,
Oct 1, 2009, 5:18:30 PM10/1/09
to
C90 said realloc(non-null, 0) did free(). C99 inverted that, saying it
does not:

The only place where 7.20.3.4 (The realloc function) mentions that
realloc may free the old object, is in the case where it returns another
object. 7.20.3 (Memory management functions) says zero-sized allocation
returns NULL, but 7.20.3.4 overrides that.

Could we have the original behavior back, please? I've seen people say
the current definition is unintentional. And it conflicts with the C99
Rationale:

7.20.3.4 The realloc function

(...) If the first argument is not null, and the second argument is
0, then the call frees the memory pointed to by the first argument,

though that goes on with

and a null argument may be returned; C99 is consistent with the
policy of not allowing zero-sized objects.

Is that supposed to mean no new object is returned but the return value
is indeterminate, or does it mean that it might free the old object and
return an inaccessible new object like malloc(0)?

Repeating from old realloc(non-null, 0) discussions:

In the latter case a program which sees a NULL return from
realloc(non-null, 0) cannot know if the old object was freed or not -
i.e. it cannot know if the NULL was a failure return (from allocating
the new object) or a success return (after freeing the old object).

Which is exactly the situation for a portable program which sees such a
NULL return today - it cannot know if it was a C99 failure return or a
C90 success return. Even if the language is C99, the library might be
C90.

--
Hallvard

lawrenc...@siemens.com

unread,
Oct 2, 2009, 11:23:20 AM10/2/09
to
Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote:
>
> The only place where 7.20.3.4 (The realloc function) mentions that
> realloc may free the old object, is in the case where it returns another
> object. 7.20.3 (Memory management functions) says zero-sized allocation
> returns NULL, but 7.20.3.4 overrides that.

7.20.3 says zero-size allocation *may* return NULL, not that it
definitely does.

> Could we have the original behavior back, please?

No. The original behavior had the terrible property that you note:

> In the latter case a program which sees a NULL return from
> realloc(non-null, 0) cannot know if the old object was freed or not -
> i.e. it cannot know if the NULL was a failure return (from allocating
> the new object) or a success return (after freeing the old object).

The new definition makes it clear: a NULL return is an error and the old
object was not freed.

> Which is exactly the situation for a portable program which sees such a
> NULL return today - it cannot know if it was a C99 failure return or a
> C90 success return. Even if the language is C99, the library might be
> C90.

So how would having the old indeterminate behavior back make things any
better? The currently required behavior is determinate and compatible
with the C89 requirements, so the expectation is that most
implementation will conform to it.
--
Larry Jones

It doesn't have a moral, does it? I hate being told how to live my life.
-- Calvin

Hallvard B Furuseth

unread,
Oct 2, 2009, 1:02:14 PM10/2/09
to
lawrenc...@siemens.com writes:
> Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote:
>>
>> The only place where 7.20.3.4 (The realloc function) mentions that
>> realloc may free the old object, is in the case where it returns another
>> object. 7.20.3 (Memory management functions) says zero-sized allocation
>> returns NULL, but 7.20.3.4 overrides that.
>
> 7.20.3 says zero-size allocation *may* return NULL, not that it
> definitely does.

Typo, sorry.

>> Could we have the original behavior back, please?
>
> No. The original behavior had the terrible property that you note:

It did not:

>> In the latter case a program which sees a NULL return from
>> realloc(non-null, 0) cannot know if the old object was freed or not -
>> i.e. it cannot know if the NULL was a failure return (from allocating
>> the new object) or a success return (after freeing the old object).
>
> The new definition makes it clear: a NULL return is an error and the old
> object was not freed.

The old meaning of NULL return was also clear, as long as you knew the
size you just had passed to realloc: If size was nonzero, the object
had not been freed, if it was zero, it had been freed.

Maybe you are thinking of realloc(ptr=NULL, 0) - C90 says both that it
beaves like malloc(0) and that the object ptr points to is freed. Since
the latter makes no sense, malloc(0) seems a reasonable interpretation.

The meaning of the realloc return value is easier to figure out in a
program that knows it runs as C99 than in a C90 program - you don't need
to know if you passed size 0, just if you passed ptr NULL. But for
other programs, the simplest way to deal with it to by now is to just
not use realloc(,0).

>> Which is exactly the situation for a portable program which sees such a
>> NULL return today - it cannot know if it was a C99 failure return or a
>> C90 success return. Even if the language is C99, the library might be
>> C90.
>
> So how would having the old indeterminate behavior back make things any
> better? The currently required behavior is determinate and compatible
> with the C89 requirements, so the expectation is that most
> implementation will conform to it.

Which C89 requirements?

Neither old nor new behavior are indeterminate. If you don't know which
C version your library has, that makes it indeterminate. In that regard
I do propose to lengthen the time in the future when that will be a real
problem so portable programs should avoid realloc(non-null, 0).

Anyway, if the current behavior it is intentional after all, then the
Rationale needs to be updated. Also it may be best to explicitly spell
out that realloc(non-null,0) no longer frees the object, since plenty of
people probably still "know" that it does.

--
Hallvard

0 new messages