What's the difference with SIZE_T and unsigned long? - c++

I'm curious with the difference with SIZE_T and unsigned long.
When I saw sizeof(SIZE_T), I trace that through declaration tracing in VS.
Then, I watched them in basetsd.h file.
typedef ULONG_PTR SIZE_T, *PSIZE_T;
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
what's difference with them?
And why c language divide them?

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

Limb in the vocabulary of arbitrary precision integer?

What does a "limb" refer to in the domain of arbitrary precision integer?
In the GNU Multiple Precision Arithmetic Library (GMP), as mentioned in comments, is the largest integer word available:
#ifdef __GMP_SHORT_LIMB
typedef unsigned int mp_limb_t;
typedef int mp_limb_signed_t;
#else
#ifdef _LONG_LONG_LIMB
typedef unsigned long long int mp_limb_t;
typedef long long int mp_limb_signed_t;
#else
typedef unsigned long int mp_limb_t;
typedef long int mp_limb_signed_t;
#endif
#endif
typedef unsigned long int mp_bitcnt_t;
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the last field points to. If _mp_size is negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
...
typedef __mpz_struct mpz_t[1];
So a limb can be a unsigned int, unsigned long int, or unsigned long long int, depending on the underlying architecture.
GMP then uses multiple limbs to store and calculate multiple precision integers, by applying a very efficient implementation of machine-specific integer code with highly optimized algorithms for multiple-precision arithmetic. The reason to use machine unsigned integers for these calculations is because integer arithmetic is simple, fast, and very realiable, whereas floating-point arithmetic and signed integer arithmetic are not as nearly standarized and portable as unsigned integer arithmetic.

C++ - Which are variable by " Uint "?

Which are variable by " Uint "? is that there are " Uint8 ", " Uint16 ", etc ...
But what are they ?
Now I have some time using C ++ but I have never needed to use these variables and cause me curious.
Thanks in advance.
uint is not a standard type. On some system uint is typedefed as
typedef unsigned int uint ;
uint is not a basic data type as mentioned in the standard. Sometimes, to make a variable to have constant size across platform [to enable portability], some typedefs are used.
You can have a look at cstdint header for more info.
With best assumption, uint should be a typedef to uint32_t
typedef uint32_t uint;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
It can help you..
if you are dealing with variable base on it's size then you can declare it like this

What should `intmax_t` be on platform with 64-bit `long int` and `long long int`?

In the C++ standard 18.4 it specifies:
typedef 'signed integer type' intmax_t;
By the standard(s) on a platform with a 64-bit long int and a 64-bit long long int which should this "signed integer type" be?
Note that long int and long long int are distinct fundamental types.
The C++ standard says:
The header defines all functions, types, and macros the same as 7.18 in the C standard.
and in 7.18 of the C standard (N1548) it says:
The following type designates a signed integer type capable of representing any value of
any signed integer type:
intmax_t
It would seem that in this case that both long int and long long int qualify?
Is that the correct conclusion? That either would be a standard-compliant choice?
Yes, your reasoning is correct. Most real-world implementations choose the lowest-rank type satisfying the conditions.
Well, assuming the GNU C library is correct (from /usr/include/stdint.h):
/* Largest integral types. */
#if __WORDSIZE == 64
typedef long int intmax_t;
typedef unsigned long int uintmax_t;
#else
__extension__
typedef long long int intmax_t;
__extension__
typedef unsigned long long int uintmax_t;
#end

Difference between different integer types

I was wondering what is the difference between uint32_t and uint32, and when I looked in the header files it had this:
types.h:
/** #brief 32-bit unsigned integer. */
typedef unsigned int uint32;
stdint.h:
typedef unsigned uint32_t;
This only leads to more questions:
What is the difference between
unsigned varName;
and
unsigned int varName;
?
I am using MinGW.
unsigned and unsigned int are synonymous, much like unsigned short [int] and unsigned long [int].
uint32_t is a type that's (optionally) defined by the C standard. uint32 is just a name you made up, although it happens to be defined as the same thing.
There is no difference.
unsigned int = uint32 = uint32_t = unsigned in your case and unsigned int = unsigned always
unsigned and unsigned int are synonymous for historical reasons; they both mean "unsigned integer of the most natural size for the CPU architecture/platform", which is often (but by no means always) 32 bits on modern platforms.
<stdint.h> is a standard header in C99 that is supposed to give type definitions for integers of particular sizes, with the uint32_t naming convention.
The <types.h> that you're looking at appears to be non-standard and presumably belongs to some framework your project is using. Its uint32 typedef is compatible with uint32_t. Whether you should use one or the other in your code is a question for your manager.
There is absolutely no difference between unsigned and unsigned int.
Whether that type is a good match for uint32_t is implementation-dependant though; an int could be "shorter" than 32 bits.

(C/C++) Structures containing unions containing structures...?

I am programming in linux, which is new to me. I am working on a project to design a 'layer 7' network protocol, and we have these packets that contain resources. And depending on the type of resource, the length of that resource would be different. I am kind of new to C/C++, and am not sure I understand unions all that well. The idea was that I would be able to make a "generic resource" type and depending on what resource it was I could just cast a void* as a pointer to this typedef structure and then call the data contained in it as anything I please and it would take care of the 'casting'. Anyways, here is what I came up with:
typedef struct _pktresource
{
unsigned char Type; // The type of the resource.
union {
struct { // This is used for variable length data.
unsigned short Size;
void *Data;
};
void *ResourceData; // Just a generic pointer to the data.
unsigned char Byte;
char SByte;
short Int16;
unsigned short UInt16;
int Int32;
unsigned int UInt32;
long long Int64;
unsigned long long UInt64;
float Float;
double Double;
unsigned int Time;
};
} pktresource, *ppktresource;
The principal behind this was simple. But when I do something like
pktresource.Size = XXXX
It starts out 4 bytes into the structure instead of 1 byte. Am I failing to grasp a major concept here? Because it feels like I am.
EDIT: Forgot to mention, when I reference
pktresource.Type
It starts at the beginning like its supposed to.
EDIT: Correction was to add pragma statements for proper alignment. After fix, the code looks like:
#pragma pack(push)
#pragma pack(1)
typedef struct _pktresource
{
unsigned char Type; // The type of the resource.
union {
struct { // This is used for variable length data.
unsigned short Size;
unsigned char Data[];
};
unsigned char ResourceData[]; // Just a generic pointer to the data.
unsigned char Byte;
char SByte;
short Int16;
unsigned short UInt16;
int Int32;
unsigned int UInt32;
long long Int64;
unsigned long long UInt64;
float Float;
double Double;
unsigned int Time;
};
} pktresource, *ppktresource;
#pragma pack(pop)
Am I failing to grasp a major concept here?
You're missing knowledge of structure alignment. Basically, it forces certain fields to be aligned by > 1 byte boundaries depending on their size. You can use #pragma to override this behavior, but that can cause interoperability issues if the structure is used anywhere outside your application.
I think the problem is alignment. By default most compilers align to the word size of the machine / OS, in this case 32 bits / 4 bytes. So, since you have that unsigned char Type field up front, the compiler is pushing the Size field to the next even 4 byte boundary.
try
#pragma pack 1
ahead of you structure definitions.
I don't know what compiler you are using, but that's good old-fashioned C code that's been regularly in use for network programming since before most of these rude kids on StackOverflow were born.