As title: is size_t always unsigned, i.e. for size_t x
, is x
always >= 0
?
问题:
回答1:
Yes. It's usually defined as something like the following (on 32-bit systems):
typedef unsigned int size_t;
Reference:
C++ Standard Section 18.1 defines size_t
is in <cstddef>
which is described in C Standard as <stddef.h>
.
C Standard Section 4.1.5 defines size_t
as an unsigned integral type of the result of the sizeof
operator
回答2:
According to the 1999 ISO C standard (C99), size_t
is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).
The standard also recommends that size_t
shouldn't have an integer conversion rank greater than long
if possible, ie casting size_t
to unsigned long
is unproblematic if the recommendation is followed.
The 1989 ANSI C standard (ANSI C) doesn't mention a minimal size or recommended conversion rank.
The 1998 ISO C++ standard (C++98) (as well as the current draft for C++0x) refers to the C standard. Section 18.1 reads:
The contents are the same as the Standard C library header
<stddef.h>
[...]
According to section 1.2, this means the library as defined by the 1990 ISO C standard (C90), including its first amendment from 1995 (C95):
The library described in clause 7 of ISO/IEC 9899:1990 and clause 7 of ISO/IEC 9899/Amd.1:1995 is hereinafter called the Standard C Library.
The parts regarding size_t
should be inherited from ANSI C: Frontmatter and section numbering aside, the standards for C90 and ANSI C are identical. I'd need a copy of the normative amendment to be sure that there weren't any relevant changes to stddef.h
, but I doubt it. The minimal size seems to be introduced with stdint.h
, ie C99.
Please also consider the following quote from section 1.2 of C++98:
All standards are subject to revision, and parties to agreements based on this International Standard are encouraged to investigate the possibility of applying the most recent editions of the standards indicated below.
回答3:
Yes, size_t is guaranteed to be an unsigned type.
回答4:
According to the standard it is unsigned, however I recall that some older implementations used a signed type for the typedef.
From an older GCC doc:
There is a potential problem with the size_t type and versions of GCC prior to release 2.4. ANSI C requires that
size_t
always be an unsigned type. For compatibility with existing systems' header files, GCC definessize_t
instddef.h
to be whatever type the system'ssys/types.h
defines it to be. Most Unix systems that definesize_t
insys/types.h
, define it to be a signed type. Some code in the library depends onsize_t
being an unsigned type, and will not work correctly if it is signed
I'm not sure how important it would be to guard against that. My code assumes it's unsigned.
回答5:
The size_t should follow the same definition as the C standard, and in several places in the C++ standard it implies it's unsigned natura (particularly in the allocator template argument definitions).
On the C++ Standard, section 18.1 (ISO/IEC 14882 - First edition 1998-01-01):
Table 15 lists as defined types: ptrdiff_t and size_t
3 The contents are the same as the Standard C library header , with the following changes: 4 The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).
The macro offsetof accepts a restricted set of type arguments in this International Standard. type shall be a POD structure or a POD union (clause 9). The result of applying the offsetof macro to a field that is a static data member or a function member is undefined. SEE ALSO: subclause 5.3.3, Sizeof, subclause 5.7, Additive operators, subclause 12.5, Free store, and ISO C subclause 7.1.6.
回答6:
Oh, this is just terrible:
vector<MyObject> arr;
Fill(arr);
size_t size = arr.size();
for(size_t i = 1; i < size - 1; ++i)
{
auto obj = arr[i];
auto next = arr[i+1];
}
Now contemplate the use case where arr is empty.