Re: Null terminated strings: bad or good?
- From: James Kuyper <jameskuyper@xxxxxxxxxxx>
- Date: Mon, 05 Jan 2009 00:18:37 GMT
JC wrote:
On Jan 4, 6:14 pm, James Kuyper <jameskuy...@xxxxxxxxxxx> wrote:....
The strongest argument I've seen for that point of view was based upon
the fact that sizeof(type) is supposed to return the size of an object
of the specified type. Since it's not possible for
sizeof(char[SIZE_MAX][SIZE_MAX]) to return the correct size of the
specified type, it must not be possible to use calloc() to allocate such
an array.
Personally, I don't see the connection. Even if calloc() is not able to
allocate such an array, that still doesn't make it possible for
sizeof(char[SIZE_MAX][SIZE_MAX]) to return the correct value.
On top of that, I don't even see the connection between sizeof(char
[SIZE_MAX][SIZE_MAX]) being undefined and char[SIZE_MAX][SIZE_MAX]
being disallowed. The array is larger than SIZE_MAX, and can exist --
nothing seems to say that just because you can't determine the size of
something with sizeof(), that something can't exist.
For any object that you can actually define in your program, with either static or automatic storage duration, "sizeof object" is supposed to give the size of that object; the standard provide no exceptions to this requirement. An implementation can meet this requirement by either limiting the maximum size of objects defined in the program to a size smaller than SIZE_MAX, or by choosing a type for size_t sufficiently big that SIZE_MAX is bigger than the largest object that can be defined.
Because there is always a way for an implementation to meet that requirement, I believe that the meaning of that requirement is precisely that an implementation must use whichever of those methods it wishes to use, in order to meet that requirement.
The requirement that sizeof(type) always give the correct size has quite different implications. Since it will always be possible to declare types that have a size greater than SIZE_MAX, no matter what value SIZE_MAX has, there's no course of action that an implementation has available to it to ensure meeting that requirement. I therefore consider that requirement to be a defect in the standard. I imagine that the actual intent was that sizeof(type) is only required to give the correct size when the correct size is smaller than SIZE_MAX. However, the standard as currently written contains no wording that actually allows sizeof to ever fail to give the correct size.
I've been told that the standard requires sizeof(type) to return the size, after conversion to size_t, even if that conversion result in a number which is not the actual size; that interpretation would avoid this problem. However, I see no such wording in the standard, not even when I looked at the precise citations that were made with the intent of supporting that claim.
Use of calloc() presents a different issue. I can declare
char (*array)[SIZE_MAX][SIZE_MAX] = calloc(SIZE_MAX, SIZE_MAX);
if(array)
{
size_t size = sizeof *array;
Now, if we reach this point in the code, then *array is an actual object, and it would appear that sizeof *array is required to return the correct size of that object, but it equally obviously cannot. Since an implementation always has the option of having calloc() fail for such allocations, it might seem that it could be argued that objects with dynamic storage duration also must be limited to SIZE_MAX bytes, just the same as objects with static or allocated storage duration.
However, there's a key difference here. "sizeof expression" does not evaluate the expression. Therefore, "sizeof *array" must produce the same result no matter what the value of 'array' is. 'array' doesn't even have to be initialized. Therefore, the problem is not the calloc() call, but the declaration of 'array'. It's not at all clear that an implementation has any legitimate reason it could give for rejecting such a declaration, but doing so is the only way available to it for avoiding the possibility of having to meet an impossible requirement.
If, instead, you wrote
char (*array)[SIZE_MAX] = calloc(SIZE_MAX, SIZE_MAX);
then there is no way to use an argument based upon 'sizeof' to conclude that this call must fail.
.
- Follow-Ups:
- Re: Null terminated strings: bad or good?
- From: Tim Rentsch
- Re: Null terminated strings: bad or good?
- From: CBFalconer
- Re: Null terminated strings: bad or good?
- From: Harald van Dijk
- Re: Null terminated strings: bad or good?
- References:
- Re: Null terminated strings: bad or good?
- From: JC
- Re: Null terminated strings: bad or good?
- From: Han
- Re: Null terminated strings: bad or good?
- From: JC
- Re: Null terminated strings: bad or good?
- From: Eric Sosman
- Re: Null terminated strings: bad or good?
- From: JC
- Re: Null terminated strings: bad or good?
- From: christian.bau
- Re: Null terminated strings: bad or good?
- From: Keith Thompson
- Re: Null terminated strings: bad or good?
- From: James Kuyper
- Re: Null terminated strings: bad or good?
- From: JC
- Re: Null terminated strings: bad or good?
- Prev by Date: Re: Zunes bug
- Next by Date: Re: Problem in printing string, created in another function.
- Previous by thread: Re: Null terminated strings: bad or good?
- Next by thread: Re: Null terminated strings: bad or good?
- Index(es):
Relevant Pages
|