B
Barry Schwarz
calloc() = malloc() + memset() ??
As long as malloc doesn't fail,
calloc(a,b) = memset(malloc(a*b),0,a*b)
calloc() = malloc() + memset() ??
Barry Schwarz said:As long as malloc doesn't fail,
And a*b doesn't overflow,
Unsigned arithmetic cannot overflow.
Given the wording in 7.20.3.1, where the allocated space constitutes a
single array, I have no idea what happens when the arithmetic product
a*b exceeds the value of SIZE_MAX. ...
calloc(a,b) must either return a pointer to enough memory to store 'a'
objects, each of size 'b' bytes, or a null pointer. If the mathematical
product of a*b is greater than SIZE_MAX, then (size_t)(a*b) bytes will
not be sufficient to meet that requirement - but the requirement still
holds. Therefore, calloc(a,b) must either return a null pointer, or
allocate sufficient memory by some mechanism other than malloc(a*b).
That is not what the standard says - "The calloc function allocates
space for an array of nmemb objects, each of whose size is size. The
space is initialized to all bits zero." Note the additional
requirement that the entire allocated space be considered a single
array. size_t must be able to hold the size in bytes of the largest
possible object, including aggregates such as arrays. When a*b is
mathematically larger then SIZE_MAX, a "successful" call to calloc
would violate this requirement. Therefore, calloc should be required
to return NULL in this case, which is what I said in the part you
snipped.
On Tue, 15 May 2012 23:03:39 -0400, James Kuyper
....
array. size_t must be able to hold the size in bytes of the largest
possible object, including aggregates such as arrays.
Citation, please?
K&R II, page 135, a stand-alone unindented paragraph approximately 1/3
of the way down the page: "C provides a compile-time unary operator
called sizeof that can be used to compute the size of any object."
K&R II is not authoritative. The C standard is. K&R II often says things
less precisely than the standard.
Also note that the words you cite from K&R II are not, in themselves,
sufficient to support your position. "can be used to compute" doesn't
require that the computation be carried out using size_t. If it were in
fact an authoritative requirement, it would not impose a constraint on
SIZE_MAX; it only indirectly constrains either UINTMAX_MAX or LDBL_MAX,
whichever is larger. For example:
char (*)p[SIZE_MAX] = calloc(2, SIZE_MAX);
long double size = 2.0L*sizeof *p;
In that code, sizeof was indeed used to calculate the size of the object
(unless calloc() failed, in which case there is no object, but the size
calculation is unaffected by that fact).
Barry Schwarz said:calloc(a,b) must either return a pointer to enough memory to store 'a'
objects, each of size 'b' bytes, or a null pointer. If the mathematical
product of a*b is greater than SIZE_MAX, then (size_t)(a*b) bytes will
not be sufficient to meet that requirement - but the requirement still
holds. Therefore, calloc(a,b) must either return a null pointer, or
allocate sufficient memory by some mechanism other than malloc(a*b).
That is not what the standard says - "The calloc function allocates
space for an array of nmemb objects, each of whose size is size. The
space is initialized to all bits zero." Note the additional
requirement that the entire allocated space be considered a single
array. size_t must be able to hold the size in bytes of the largest
possible object, including aggregates such as arrays. [snip]
Regardless of how the computation is carried out, the result must fit
in a size_t.
There is no requirement that size_t be the widest possible unsigned
type. ...
Agreed.
... Surely SIZE_MAX cannot exceed UINTMAX_MAX. ...
Agreed.
... I don't understand
how UINTMAX_MAX enters into this discussion.
char (*)p[SIZE_MAX] = calloc(2, SIZE_MAX);
long double size = 2.0L*sizeof *p;
In that code, sizeof was indeed used to calculate the size of the object
(unless calloc() failed, in which case there is no object, but the size
calculation is unaffected by that fact).
While it is not very likely, it is possible for SIZE_MAX to exceed
LDBL_MAX (1E37 bytes is a large object and size_t would need to be in
excess of 120 bits). In that case, the implicit conversion in your
multiplication invokes undefined behavior (6.3.1.4-2). ...
My only assertion was that since the result of calloc(a,b) is to be
treated as a single array, calloc should fail if a*b mathematically
exceeds SIZE_MAX.
... I didn't address whether SIZE_MAX could be
converted to a real floating type or any other integer type (though it
seems obvious it should be convertible to a uintmax_t).
The wording is unchanged in n1570.
[Note: corrected typo in Subject: header]
Regardless of how the computation is carried out, the result must fit
in a size_t.
Citation, please?
An assertion for which you've provided no citations from the standard,
nor any arguments based upon such citations. Even the citation you have
provided from K&R II fails to specify any such requirement.
The wording of what? All of the citations from the standard so far have
been made by me, and none of them are worded in such a way as to
conflict with the implementation I described.
[Note: corrected typo in Subject: header]
On Thu, 17 May 2012 09:09:12 -0400, James Kuyper
On 05/16/2012 07:30 PM, Barry Schwarz wrote:
On Wed, 16 May 2012 07:18:35 -0400, James Kuyper
On 05/15/2012 11:38 PM, Barry Schwarz wrote:
calloc(a,b) must either return a pointer to enough memory to store 'a'
objects, each of size 'b' bytes, or a null pointer. If the mathematical
product of a*b is greater than SIZE_MAX, then (size_t)(a*b) bytes will
not be sufficient to meet that requirement - but the requirement still
holds. Therefore, calloc(a,b) must either return a null pointer, or
allocate sufficient memory by some mechanism other than malloc(a*b).
...
array. size_t must be able to hold the size in bytes of the largest
possible object, including aggregates such as arrays.
Citation, please?
K&R II, page 135, a stand-alone unindented paragraph approximately 1/3
of the way down the page: "C provides a compile-time unary operator
called sizeof that can be used to compute the size of any object."
K&R II is not authoritative. The C standard is. K&R II often says things
less precisely than the standard. ...
Also note that the words you cite from K&R II are not, in themselves,
sufficient to support your position. "can be used to compute" doesn't
require that the computation be carried out using size_t. If it were in
Regardless of how the computation is carried out, the result must fit
in a size_t.
Citation, please?
Unless I misread your original response, which has been snipped beyond
recognition above, the result in question was the evaluation of the
sizeof operator. ...
... Is there some debate about the type of this
evaluation?
I'll agree to disagree.
So my quote from 7.20.3.1 wasn't from the standard?
We can disagree on whether I'm interpreting it correctly but I did
provide it. You even quoted it back to me in your message of 15 May
at 2303Z. Looking at snipped quotes in a response is not a good way
to remember who said what
Barry Schwarz said:K&R II, page 135, a stand-alone unindented paragraph approximately 1/3
of the way down the page: "C provides a compile-time unary operator
called sizeof that can be used to compute the size of any object."
James Kuyper said:[Note: corrected typo in Subject: header]
On 05/17/2012 02:48 PM, Barry Schwarz wrote:
On Thu, 17 May 2012 09:09:12 -0400, James Kuyper
On 05/16/2012 07:30 PM, Barry Schwarz wrote:
On Wed, 16 May 2012 07:18:35 -0400, James Kuyper
On 05/15/2012 11:38 PM, Barry Schwarz wrote:
calloc(a,b) must either return a pointer to enough memory to store 'a'
objects, each of size 'b' bytes, or a null pointer. If the mathematical
product of a*b is greater than SIZE_MAX, then (size_t)(a*b) bytes will
not be sufficient to meet that requirement - but the requirement still
holds. Therefore, calloc(a,b) must either return a null pointer, or
allocate sufficient memory by some mechanism other than malloc(a*b).
...
array. size_t must be able to hold the size in bytes of the largest
possible object, including aggregates such as arrays.
Citation, please?
K&R II, page 135, a stand-alone unindented paragraph approximately 1/3
of the way down the page: "C provides a compile-time unary operator
called sizeof that can be used to compute the size of any object."
K&R II is not authoritative. The C standard is. K&R II often says things
less precisely than the standard.
...
Also note that the words you cite from K&R II are not, in themselves,
sufficient to support your position. "can be used to compute" doesn't
require that the computation be carried out using size_t. If it were in
Regardless of how the computation is carried out, the result must fit
in a size_t.
Citation, please?
Unless I misread your original response, which has been snipped beyond
recognition above, the result in question was the evaluation of the
sizeof operator. ...
No, the result in question was the calculation of "... the size of any
object." The text saying so was yours, not mine, and it has survived all
snipping.
... Is there some debate about the type of this
evaluation?
No, there's a debate about whether that type is required to be capable
of holding "the size of any object". I contend it's only required to
hold the size of types, whether or not there's an object of that type.
Passing a type to sizeof, either directly or through an expression of
that type, whose size cannot be represented in size_t, renders the
behavior undefined
by reason of a lack of definition (or more precisely, by reason
of an internally contradictory definition of the behavior).
Tim Rentsch said:Which is it? Does the Standard require sizeof to produce a value
that must fit in a size_t, or is the behavior of sizeof undefined in
some cases? They can't both be true.
Previous discussions have, I think, reached concensus that there are two
valid ways to resolve the apparent contradiction: An implementation is
free to disallow declarations (including abstract ones) that would
specify a size that is too big to fit in a size_t. An implementation is
also free to accept such declarations and declare that the behavior of
sizeof is undefined in that case. Both lead to completely consistent
readings of the standard and the committee has not felt compelled to
bless one over the other.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.