When to use uint16_t vs int and when to use the cast type

I have 2 questions about C programming:

  • For int

    , and uint16_t

    , long

    and uint32_t

    , etc. When should you use types u*_t

    instead of int

    , 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?

+3


source to share


4 answers


  • 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 (hence uint16_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 *

    to void *

    (nominally through char *

    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, and long

    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.



+3


source


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.



Wikipedia has additional information

0


source


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.

0


source


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 ...

-3


source







All Articles