Anonymous | Login | 2025-01-22 18:31 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000400 | [1003.1(2008)/Issue 7] System Interfaces | Objection | Error | 2011-03-24 16:37 | 2014-04-10 16:00 | ||
Reporter | eblake | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | Eric Blake | ||||||
Organization | Red Hat | ||||||
User Reference | ebb.realloc | ||||||
Section | realloc | ||||||
Page Number | 1754 | ||||||
Line Number | 56027 | ||||||
Interp Status | Approved | ||||||
Final Accepted Text | Note: 0000772 | ||||||
Summary | 0000400: realloc wording conflicts with C99 | ||||||
Description |
The C committee considered three possibilities: 1. Do nothing and accept the fact that some C99 implementations may not be able to conform to the requirements of the C99 standard in this regard for compatibility reasons. 2. Change C to more closely align with the POSIX requirements so as to make the existing implementatins conforming. This resolution is being sought by the POSIX group and is also preferred by the implementers of the affected implementations. 3. Change both the C and POSIX standards to require realloc() to always attempt to allocate space even for zero-size requests. This would simplify the specification and, at least in theory, also make it easier to write portable programs. This option would require the support of the implementers of the affected implementations. Without such support this option becomes equivalent to option 1 above. The outcome of this discussion is that if realloc returns NULL, it has failed, and the original memory has not been freed. The POSIX words came from C90, and these were changed for C99. POSIX failed to pick up the change See N872 item 19c. Unfortunately this breaks several existing implementations. However, those implementer present (Sun/Oracle, Apple, IBM, HP) all agreed that they were prepared to change their implementations. NOTE: Since the text at the top of realloc() states: The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard. I am not sure we have the wiggle room to do anything but DEFECT situation. |
||||||
Desired Action |
POSIX Change requested by C99: Page 1754 line 56030 Change: The realloc() function shall change the size of the memory object pointed to by ptr to the size specified by size. The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed. If the new size is larger, the contents of the newly allocated portion of the object are unspecified. If size is 0 and ptr is not a null pointer, the object pointed to is freed. to The realloc() function shall deallocate the old object pointed to by ptr and return a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values. Page 1754 line 56046 change Upon successful completion with a size not equal to 0, realloc() shall return a pointer to the (possibly moved) allocated space. to Upon successful completion, realloc() shall return a pointer to the (possibly moved) allocated space. At line 56047-8 change: If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. to If size is 0, either: * a null pointer shall be returned <CX>and errno set to EINVAL</CX>, or * unique pointer that can be successfully passed to free() shall be returned, and the memory object pointed to by ptr shall be freed. Add after line 56049: If realloc() returns NULL, the memory referenced by ptr is not changed. Add after 56052: The realloc() function may fail if: EINVAL size is 0 and the implementation does not support 0 sized allocations. |
||||||
Tags | c99, tc1-2008 | ||||||
Attached Files | |||||||
|
Relationships | |||||||||||||||||||||||||
|
Notes | |
(0000723) eblake (manager) 2011-03-24 17:08 |
glibc is impacted by the outcome of this bug: http://sourceware.org/bugzilla/show_bug.cgi?id=12547 [^] |
(0000725) geoffclare (manager) 2011-03-25 09:48 |
The line 56049 addition should be worded: If realloc() returns a null pointer, the memory referenced by ptr shall not be changed. I think the EINVAL error should be "shall fail", not "may fail", because although the behaviour of returning an EINVAL error for size 0 is optional, the implementation choice is stated in the error description: "... and the implementation does not support 0 sized allocations." |
(0000726) eblake (manager) 2011-03-25 20:22 |
A fourth possibility not covered by the C99's recommendations: Change line 56034 [realloc DESCRIPTION]: If size is 0 and ptr is not a null pointer, the object pointed to is freed. to: <CX>If size is 0 and ptr is not a null pointer, behavior is unspecified; portable applications shall ensure that a size of 0 is only used when ptr is a null pointer.</CX> Change line 56047 [RETURN VALUE]: If size is 0, to: If size is 0 and ptr is a null pointer, Change line 56058 [RATIONALE]: None. to two paragraphs: The C99 standard requires that for a non-null pointer ptr, realloc(ptr,0) will either return a zero-size allocation (as if by malloc(0)) or leave ptr unchanged (because a NULL return indicates failure). However, there are existing implementations that take a third approach of freeing ptr while still returning NULL. While these implementations do not comply with C99, they are still permitted by this version of POSIX. An application that assumes C99 semantics by calling free(ptr) after a NULL return from realloc(ptr,0) failure will end up with undefined behavior of freeing an already-freed pointer. Therefore, this standard completely avoids the portability issues by instead requiring that applications never use realloc with a non-null pointer but zero size. This restriction does not represent a conflict with the ISO C standard. An implementation may choose whether it wishes to comply to both C99 and POSIX (use of size 0 will have some guarantees per C99, although a conforming POSIX application will not trigger those guarantees), or just POSIX. Note that while there are several places in the standard where <CX> provides tighter implementation constraints (not all C99 implementations comply with POSIX), I think this would be the first case of the converse (a case where <CX> provides looser implementation constraints, that is, where a POSIX-compliant implementation need not obey C99. On the other hand, where this standard is tighter than C99, it implies that an application that conforms to this standard will not necessarily behave the same way in all other C99 environments; whereas this requirement to avoid the unspecified behavior of the looser implementation guarantees that an application written to this standard will never trigger portability problems whether run on a C99 environment or a legacy environment. Given the extreme reluctance to change existing implementations, this may be the only solution for POSIX to continue to cater to implementations such as glibc, while still permitting implementations that obey C99. |
(0000727) eblake (manager) 2011-03-25 20:26 |
Note also that this standard has already had a track record of marking some C99 requirements as obsolescent and not to be relied on by portable programs, such as gets(), which gives more precedence to the notion of declaring realloc(ptr,0) as <OB>. |
(0000734) nick (manager) 2011-04-01 22:29 |
Sent to the SC22WG14 email reflector: The Austin Group has been studying this problem (see http://austingroupbugs.net/view.php?id=400) [^] and trying to resolve any conflict with C. This was also examined by WG14 during the London meeting, where the resolution was "POSIX should conform to the requirements of C". The Austin Group agrees with this resolution. However, during our discussions, we have found the following in the C standard (using refs to C99, not C1x): Point 1: Objects cannot be zero sized. 6.2.6.1(2) Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, Point 2: realloc(NULL, 0) is required to behave like malloc(0), and malloc states "7.20.3.3(2) The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate." Since objects cannot be zero sized, returning a non-null pointer is at best questionable. However, this argues that realloc(p, 0) should always fail. Point 3: Explicit permission to succeed AND return NULL is granted: "7.20.3(1) If the size of the space requested is zero, the behavior is implementation- defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object." [this refers to calloc, malloc and realloc]. It has been claimed that if realloc(p,0) returns a null pointer, that indicates that "the new object cannot be allocated" and so the old object remains alive. However, that interpretation is not clear, and the two separate sentences in 7.20.3.1 about null pointers are distinct cases, and the second does not necessarily imply the first. The POSIX words currently follow the original C89 text, and not the C99 update. They state: "If size is 0 and ptr is not a null pointer, the object pointed to is freed. ...RETURNS... If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned." The C99 words state "7.20.3.4(2) The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size." This would appear to allow an implementation to deallocate the space and then return NULL (without setting errno). Additionally, "7.20.3(3) ... or if the space has been deallocated by a call to the free or realloc function..." strongly suggests that realloc(ptr, 0) is a valid way to free ptr. So, the Austin Group currently does not believe that POSIX conflicts with C, and that it is permissible for realloc(p, 0) (where p is non-NULL) to free the space allocated and return NULL. In POSIX, it is acceptable to set errno to zero before the call, and test it afterwards to see if the pointer has been freed or not. Our current survey has shown that the following implementations free the pointer and return NULL : Glibc (GNU/Linux) AIX HP-UX Solaris OSF/1 There is strong resistance from at least one of these to changing their implementation, in the belief that this would make current, memory leak free, conforming code become both non-conforming and leaking. -- Nick Stoughton Austin Group/WG14 Liaison |
(0000735) nick (manager) 2011-04-01 22:30 |
Reply on SC22WG14 reflector: What WG 14 has been saying is that that interpretation is incorrect. Referencing the latest C1x draft: 1. 7.22.3.5p4, "Returns," states "The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated." In other words, null means failure. 2. 7.22.3p1 states "If the space cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object." This, together with the previous quote, means that the function can either succeed and return a valid pointer, or fail and return a null pointer. 3. 7.22.3.5p1 states "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged." This, together with the previous two quotes, means that if a null pointer is returned, the operation has failed and the old object is not deallocated. You mentioned the fact that objects cannot be zero sized. That is why the wording is the way it is. If we had zero-sized objects, we could just say that an allocation of size zero returns a pointer to just past the end of a zero-sized object (and that is why the pointer cannot be dereferenced). Instead, we have to say the same thing without talking about zero-sized objects. |
(0000746) nick (manager) 2011-04-21 15:25 edited on: 2011-04-28 15:17 |
Current proposed wording: Page 1754 line 56030 Change: The realloc() function shall change the size of the memory object pointed to by ptr to the size specified by size. The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed. If the new size is larger, the contents of the newly allocated portion of the object are unspecified. If size is 0 and ptr is not a null pointer, the object pointed to is freed. to The realloc() function shall deallocate the old object pointed to by ptr and return a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values. If the size of the space requested is zero, the behavior shall be implementation-defined: either a null pointer is returned, or the behavior shall be as if the size were some nonzero value, except that the returned pointer shall not be used to access an object. Page 1754 line 56046 change Upon successful completion with a size not equal to 0, realloc() shall return a pointer to the (possibly moved) allocated space. to Upon successful completion, realloc() shall return a pointer to the (possibly moved) allocated space. At line 56047-8 change: If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. to If size is 0, either: * a null pointer shall be returned <CX>and errno set to an implementation defined value</CX>, or * unique pointer that can be successfully passed to free() shall be returned, and the memory object pointed to by ptr shall be freed. The application shall ensure that the pointer is not used to access an object. Add after line 56049: If realloc() returns NULL <CX>and errno has been set to a ENOMEM</CX>, the memory referenced by ptr shall not be changed. At line 56056 (Application Usage), change: None. to The description of realloc() has been modified from previous versions of this standard to align with C99. Previous versions explicitly permitted a call to realloc(p, 0) to free the space pointed to by p and return NULL. While this behavior could be interpreted as permitted by this version of the standard, the C language committee have indicated that this interpretation is incorrect. Applications should assume that if realloc returns a null pointer, the space pointed to be p has not been freed. Since this could lead to double-frees, implementations should also set errno if a null pointer actually indicates a failure, and applications should only free the space if errno was changed. Change at line 56060 (Future Directions) from: None. to This standard defers to the C standard. While that standard currently has language that might permit realloc(p, 0), where p is not a null pointer, to free p while still returning a null pointer, the committee responsible for that standard is considering clarifying the language to explicitly prohibit that alternative. |
(0000772) msbrown (manager) 2011-04-28 15:25 |
Interpretation response ------------------------ The standard states its realloc specification , and conforming implementations must conform to this. However, concerns have been raised about this which are being referred to the sponsor. Rationale: ------------- The C standards WG has given us guidance on this issue. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- Take the actions as described in Note: 0000746 |
(0000845) ajosey (manager) 2011-06-16 10:16 |
Interpretation proposed 16 June 2011 for final 30 day review |
(0000907) ajosey (manager) 2011-07-29 06:14 |
The interpretation is now approved. |
(0002223) eblake (manager) 2014-04-10 16:00 |
http://open-std.org/JTC1/SC22/WG14/www/docs/dr_400.htm [^] |
Issue History | |||
Date Modified | Username | Field | Change |
2011-03-24 16:37 | eblake | New Issue | |
2011-03-24 16:37 | eblake | Status | New => Under Review |
2011-03-24 16:37 | eblake | Assigned To | => ajosey |
2011-03-24 16:37 | eblake | Name | => Eric Blake |
2011-03-24 16:37 | eblake | Organization | => Red Hat |
2011-03-24 16:37 | eblake | User Reference | => ebb.realloc |
2011-03-24 16:37 | eblake | Section | => realloc |
2011-03-24 16:37 | eblake | Page Number | => 1754 |
2011-03-24 16:37 | eblake | Line Number | => 56027 |
2011-03-24 16:37 | eblake | Interp Status | => --- |
2011-03-24 16:38 | eblake | Relationship added | parent of 0000374 |
2011-03-24 16:38 | eblake | Tag Attached: c99 | |
2011-03-24 16:38 | eblake | Tag Attached: tc1-2008 | |
2011-03-24 17:08 | eblake | Note Added: 0000723 | |
2011-03-25 09:48 | geoffclare | Note Added: 0000725 | |
2011-03-25 20:22 | eblake | Note Added: 0000726 | |
2011-03-25 20:26 | eblake | Note Added: 0000727 | |
2011-03-31 15:29 | msbrown | Note Added: 0000731 | |
2011-03-31 15:30 | msbrown | Note Deleted: 0000731 | |
2011-04-01 22:29 | nick | Note Added: 0000734 | |
2011-04-01 22:30 | nick | Note Added: 0000735 | |
2011-04-21 15:25 | nick | Note Added: 0000746 | |
2011-04-28 15:17 | nick | Note Edited: 0000746 | |
2011-04-28 15:17 | nick | Note Edited: 0000746 | |
2011-04-28 15:25 | msbrown | Interp Status | --- => Pending |
2011-04-28 15:25 | msbrown | Note Added: 0000772 | |
2011-04-28 15:25 | msbrown | Status | Under Review => Interpretation Required |
2011-04-28 15:25 | msbrown | Resolution | Open => Accepted As Marked |
2011-04-28 15:26 | msbrown | Final Accepted Text | => Note: 0000746 |
2011-04-28 15:28 | msbrown | Final Accepted Text | Note: 0000746 => Note: 0000772 |
2011-06-16 10:16 | ajosey | Interp Status | Pending => Proposed |
2011-06-16 10:16 | ajosey | Note Added: 0000845 | |
2011-07-29 06:14 | ajosey | Interp Status | Proposed => Approved |
2011-07-29 06:14 | ajosey | Note Added: 0000907 | |
2011-12-06 16:12 | nick | Relationship added | parent of 0000524 |
2011-12-12 10:27 | geoffclare | Relationship added | related to 0000526 |
2013-04-16 13:06 | ajosey | Status | Interpretation Required => Closed |
2013-05-09 15:56 | eblake | Relationship added | related to 0000688 |
2014-04-10 16:00 | eblake | Note Added: 0002223 |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |