When to use uint16_t vs int and when to use the cast type
I have 2 questions about C programming:
-
For
int
, anduint16_t
,long
anduint32_t
, etc. When should you use typesu*_t
instead ofint
,long
etc.? It was difficult for me to choose which one is best for my program. -
When do I need to enter a type? I have the following instruction in my program:
long * src; long * dst; ... memcpy(dst, src, len);
My friend changes this to
memcpy((char *)dst, (char *)src, len).
This is just an example that I ran into. Generally, I get confused when a throw is required?
source to share
-
Use simple types (
int
etc.) unless you need a well-sized type. You might need a well-sized type if you are working with a wired protocol that specifies that the size field should be a 2-byte unsigned integer (henceuint16_t
), but for most of the work, use simple types most of the time. (This one has some caveats, but most of the time most people can work with common types for simple digital work.If you are working with a set of interfaces, use the types dictated by the interfaces.If you use multiple interfaces and conflict types, you will have to think about which at that time - or change one or both interfaces.) -
The tides added by your friend are pointless. The actual prototype
memcpy()
is:void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
The compiler converts the values
long *
tovoid *
(nominally throughchar *
due to the cast), all of which almost always fail.More generally, you use cast when you need to change the type of something. One place you might need is bitwise operations where you want a 64-bit result, but the operands are 32-bit and leave the conversion until the bitwise operations produce a different result from what you wanted. For example, if we assume that the system, where
int
is 32 bits, andlong
is 64 bits.unsigned int x = 0x012345678; unsigned long y = (~x << 22) | 0x1111;
This would compute
~x
as a 32-bit count, and the shift would be done over the 32-bit count, losing a few bits. On the contrary:unsigned long z = (~(unsigned long)x << 22) | 0x1111;
ensures that the calculation is done in 64-bit arithmetic and does not lose any bits from the original value.
source to share
The size of "classic" types such as int
and long int
may differ between systems. This can cause problems, for example, when accessing files with fixed-width data structures. For example, it is currently a 64-bit integer on newer systems, but only 32-bit on older systems. int
long
The types intN_t
and uintN_t
were introduced with C99 and are defined in <inttypes.h>
. Since they explicitly indicate the number of bits, they remove any ambiguity. Generally, you should use these types in preference if you are worried about making your code portable at all.
source to share
If you don't want to rely on your compiler, use the predefined types provided by the standard library headers. Every C library you intend to compile with is guaranteed to assign the correct types to at least have the size to hold the size values ββdeclared by their types.
In your other specific case, it might be assumed that he made this type a cast just because he wanted to point out to other readers that the two pointers actually contain character characters. Or maybe he's a very old guy who remembers times when there was no type void
and the "lowest common divisor" was a pointer to char
. In my life as a developer, if I want to emphasize some of my actions, I will make an explicit cast, even if it is inherently redundant.
source to share
For your 1st question, take a look at fooobar.com/questions/525 / ...
Basically, _t is the real name of the standard type and without it, it is a definition of the same type. u is for unsigned, which does not allow a negative number.
As for your second question, you often need to use when a function is called parameters of a different type that you pass. You can look here for casting tips, or here ...
source to share