Thursday, May 27, 2021

Digest for comp.lang.c++@googlegroups.com - 5 updates in 1 topic

Keith Thompson <Keith.S.Thompson+u@gmail.com>: May 27 03:33PM -0700


> Why? size_t is guaranteed to hold the size of any object, which implies that
> it must be large enough to accomodate an object the size of the virtual address
> space. Generally it's minimum size in bits is the same as long.
 
That's likely to be true, but it's not absolutely guaranteed.
 
size_t is intended to hold the size of any single object, but it may
not be able to hold the sum of sizes of all objects or the size of
the virtual address space. An implementation might restrict the
size of any single object to something smaller than the size of
the entire virtual address space. (Think segments.)
 
Also, I haven't found anything in the standard that says you
can't at least try to create an object bigger than SIZE_MAX bytes.
calloc(SIZE_MAX, 2) attempts to allocate such an object, and I don't
see a requirement that it must fail. If an implementation lets you
define a named object bigger than SIZE_MAX bytes, then presumably
applying sizeof to it would result in an overflow, and therefore
undefined behavior.
 
Any reasonable implementation will simply make size_t big enough
to hold the size of any object it can create, but I don't see a
requirement for it.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Lynn McGuire <lynnmcguire5@gmail.com>: May 27 05:45PM -0500

On 5/27/2021 4:59 PM, Scott Lurndal wrote:
 
> Why? size_t is guaranteed to hold the size of any object, which implies that
> it must be large enough to accomodate an object the size of the virtual address
> space. Generally it's minimum size in bits is the same as long.
 
// get the size of the output file
fseek (pOutputFile, 0, SEEK_END);
__int64 outputFileLength = _ftelli64 (pOutputFile) + 42; // give it
some slop
size_t outputFileLengthSizeT = 0;
if (outputFileLength < SIZE_MAX)
outputFileLengthSizeT = (size_t) outputFileLength;
fseek (pOutputFile, 0, SEEK_SET);
// need to preallocate the space in case the output file is a gigabyte
or more, PMR 6408
// if the try fails then just don't store the output file in the flowsheet
if (outputFileLengthSizeT > 0)
{
try
{
// PMR 6408 will cause this to fail
outputFileBuffer.reserve (outputFileLengthSizeT);
 
Thanks,
Lynn
Keith Thompson <Keith.S.Thompson+u@gmail.com>: May 27 03:58PM -0700

>> it must be large enough to accomodate an object the size of the virtual address
>> space. Generally it's minimum size in bits is the same as long.
 
> That's likely to be true, but it's not absolutely guaranteed.
 
My apologies, I was wrong.
 
> the virtual address space. An implementation might restrict the
> size of any single object to something smaller than the size of
> the entire virtual address space. (Think segments.)
 
I believe this is still correct.
 
 
> Any reasonable implementation will simply make size_t big enough
> to hold the size of any object it can create, but I don't see a
> requirement for it.
 
The above is correct in C, but not in C++, which makes an additional
guarantee that C doesn't. C++17 21.2.4 [support.types.layout] says:
 
The type size_t is an implementation-defined unsigned integer type
that is large enough to contain the size in bytes of any object
(8.3.3).
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Lynn McGuire <lynnmcguire5@gmail.com>: May 27 06:17PM -0500

On 5/27/2021 5:58 PM, Keith Thompson wrote:
 
> The type size_t is an implementation-defined unsigned integer type
> that is large enough to contain the size in bytes of any object
> (8.3.3).
 
Except the actual size of a FILE * object in the filesystem. Size_t can
hold the size of the FILE * structure but if the actual file size is
greater than 4 GB in a Win32 program, size_t will be wrong.
 
Now if the program is Win64, size_t can hold the actual size of any file
in the filesystem.
 
#ifdef _WIN64
typedef unsigned __int64 size_t;
typedef __int64 ptrdiff_t;
typedef __int64 intptr_t;
#else
typedef unsigned int size_t;
typedef int ptrdiff_t;
typedef int intptr_t;

No comments: