unsigned int vs. size_t
The size_t
type is the unsigned integer type that is the result of the sizeof
operator (and the offsetof
operator), so it is guaranteed to be big enough to contain the size of the biggest object your system can handle (e.g., a static array of 8Gb).
The size_t
type may be bigger than, equal to, or smaller than an unsigned int
, and your compiler might make assumptions about it for optimization.
You may find more precise information in the C99 standard, section 7.17, a draft of which is available on the Internet in pdf format, or in the C11 standard, section 7.19, also available as a pdf draft.
Difference between size_t and unsigned int?
if it is use to represent non negative value so why we not using
unsigned int
instead ofsize_t
Because unsigned int
is not the only unsigned integer type. size_t
could be any of unsigned char
, unsigned short
, unsigned int
, unsigned long
or unsigned long long
, depending on the implementation.
Second question is that
size_t
andunsigned int
are interchangeable or not and if not then why?
They aren't interchangeable, for the reason explained above ^^
.
And can anyone give me a good example of size_t and its brief working ?
I don't quite get what you mean by "its brief working". It works like any other unsigned type (in particular, like the type it's typedeffed to). You are encouraged to use size_t
when you are describing the size of an object. In particular, the sizeof
operator and various standard library functions, such as strlen()
, return size_t
.
Bonus: here's a good article about size_t
(and the closely related ptrdiff_t
type). It reasons very well why you should use it.
int vs unsigned int vs size_t
The C++ standard library would almost certainly use a std::size_t
for such a type.
Using a signed
type is obviously not desirable and, ideally, you want to use a type that lends itself well to having an object that supports iterability.
From the outset I recommend you use typedef std::size_t MySize;
within your class, mainly to future-proof yourself. That would be the most sensible choice.
Can I just use unsigned int instead of size_t?
size_t
is the most correct type to use when describing the sizes of arrays and objects. It's guaranteed to be unsigned and is supposedly "large enough" to hold any object size for the given system. Therefore it is more portable to use for that purpose than unsigned int
, which is in practice either 16 or 32 bits on all common computers.
So the most canonical form of a for
loop when iterating over an array is actually:
for(size_t i=0; i<sizeof array/sizeof *array; i++)
{
do_something(array[i]);
}
And not int i=0;
which is perhaps more commonly seen even in some C books.
size_t
is also the type returned from the sizeof
operator. Using the right type might matter in some situations, for example printf("%u", sizeof obj);
is formally undefined behavior, so it might in theory crash printf or print gibberish. You have to use %zu
for size_t
.
It is quite possible that size_t
happens to be the very same type as unsigned long
or unsigned long long
or uint32_t
or uint64_t
though.
Why are size_t and unsigned int slower than int?
Inspecting the generated assembly for all 3 variants (int
, unsigned
, size_t
), the big difference is that in the int
case the loop in the sort
function is unrolled and uses SSE instructions (working on 8 ints at a time), while in the other 2 cases it does neither. Interestingly enough, the sort
function is called in the int
case, while it is inlined into main
in the other two (likely due to the increased size of the function due to the loop unrolling).
I'm compiling from the command line using cl /nologo /W4 /MD /EHsc /Zi /Ox
, using dumpbin
to get the disassembly, with toolset Microsoft (R) C/C++ Optimizing Compiler Version 19.12.25830.2 for x64
.
I get execution times of around 30 seconds for int
and 100 seconds for the other two.
size_t vs int in C++ and/or C
In general, size_t
should be used whenever you are measuring the size of something. It is really strange that size_t
is only required to represent between 0 and SIZE_MAX
bytes and SIZE_MAX
is only required to be 65,535...
The other interesting constraints from the C++ and C Standards are:
- the return type of
sizeof()
issize_t
and it is an unsigned integer operator new()
takes the number of bytes to allocate as asize_t
parametersize_t
is defined in<cstddef>
SIZE_MAX
is defined in<limits.h>
in C99 but not mentioned in C++98?!size_t
is not included in the list of fundamental integer types so I have always assumed thatsize_t
is a type alias for one of the fundamental types:char
,short int
,int
, andlong int
.
If you are counting bytes, then you should definitely be using size_t
. If you are counting the number of elements, then you should probably use size_t
since this seems to be what C++ has been using. In any case, you don't want to use int
- at the very least use unsigned long
or unsigned long long
if you are using TR1. Or... even better... typedef
whatever you end up using to size_type
or just include <cstddef>
and use std::size_t
.
What's the difference with SIZE_T and unsigned long?
SIZE_T
is a Windows datatype, not a standard type. As for the difference, it is that SIZE_T
may not be an unsigned long
. Take a look at this page which lists Windows datatypes. The entry for SIZE_T
says:
The maximum number of bytes to which a pointer can point. Use for a
count that must span the full range of a pointer.This type is declared in BaseTsd.h as follows:
typedef ULONG_PTR SIZE_T;
And ULONG_PTR
has the following entry:
An unsigned
LONG_PTR
.This type is declared in BaseTsd.h as follows:
#if defined(_WIN64)
typedef unsigned __int64 ULONG_PTR;
#else
typedef unsigned long ULONG_PTR;
#endif
So it could be unsigned long
, or it could be unsigned __int64
. In your case ULONG_PTR
and in turn SIZE_T
are defined as unsigned long
but this may not always be the case.
In your specific case, ULONG_PTR
is defined as _W64 unsigned long
, however I believe this is identical to unsigned __int64
.
Related Topics
To_String Is Not a Member of Std, Says G++ (Mingw)
Which Is Faster: Stack Allocation or Heap Allocation
How to "Return an Object" in C++
C++ Templates That Accept Only Certain Types
Constructor Initialization-List Evaluation Order
Why Should the Copy Constructor Accept Its Parameter by Reference in C++
C/C++ With Gcc: Statically Add Resource Files to Executable/Library
Why Do Objects of the Same Class Have Access to Each Other'S Private Data
C++ Virtual Function from Constructor
When to Use Dynamic Vs. Static Libraries
How to Determine If a String Is a Number With C++
What Is the Correct Way of Using C++11'S Range-Based For
Finding C++ Static Initialization Order Problems
Which, If Any, C++ Compilers Do Tail-Recursion Optimization
Example For Boost Shared_Mutex (Multiple Reads/One Write)
C++ Deprecated Conversion from String Constant to 'Char*'