# V673. More than N bits are required to store the value, but the expression evaluates to the T type which can only hold K bits.

The analyzer has detected a potential error in the expression that uses shift operations. They cause an overflow and loss of the most significant bit values.

Let's start with a simple example:

    std::cout << (77u << 26);

The value of the `77u << 26` expression is 5167382528 (0x134000000) and this expression is of the `unsigned int` type. This means that the most significant bits will be truncated, and the 872415232 (0x34000000) value will be printed.

Overflows caused by shift operations usually indicate a logic error or a typo in the code. For example, a programmer intended to define `77u` as an octal number, then the correct code should look like this:

    std::cout << (077u << 26);

No overflow occurs now; the value of the `077u << 26` expression is 4227858432 (0xFC000000).

If you need the 5167382528 number to be printed , define 77 as the 64-bit type. For example:

    std::cout << (77ui64 << 26);

Now, to the cases one may encounter in real life. The two samples below are taken from real applications.

Example 1.

    typedef __UINT64 Ipp64u;
    #define MAX_SAD 0x07FFFFFF
    ....
    Ipp64u uSmallestSAD;
    uSmallestSAD = ((Ipp64u)(MAX_SAD<<8));

A programmer wants the`0x7FFFFFF00` value to be written into the `uSmallestSAD` 64-bit variable. However, the variable stores the `0xFFFFFF00` value instead, and the most significant bits will be truncated because the `MAX_SAD<<8` expression is of the `int` type. The programmer knew that and decided to use explicit type casting but made a mistake when placing parentheses. The example shows that even ordinary mistakes can easily cause such bugs. Here is the fixed code:

    uSmallestSAD = ((Ipp64u)(MAX_SAD))<<8;

Example 2.

    #define MAKE_HRESULT(sev,fac,code) \
      ((HRESULT) \
       (((unsigned long)(sev)<<31) | \
        ((unsigned long)(fac)<<16) | \
        ((unsigned long)(code))) )

    *hrCode = MAKE_HRESULT(3, FACILITY_ITF, messageID);

The function must generate an error message in a variable of the `HRESULT` type. To do this, the developer used the `MAKE_HRESULT` macro—but incorrectly, assuming that the first parameter, `severity`, could range from 0 to 3. Most likely, they confused it with the format used to generate error codes when working with the `GetLastError()` / `SetLastError()` functions.

The `MAKE_HRESULT` macro can take either 0 (success) or 1 (failure) as the first argument. For more details on this topic, see the thread on the forum of the CodeGuru website: Warning! MAKE_HRESULT macro doesn't work.

Since 3 is passed as the first actual argument, an overflow occurs, and 3 "turns into" 1. Because of this unexpected event, the error does not affect the program execution. However, this example shows that code often works by sheer luck, and not because it was written correctly.

The fixed code:

    *hrCode = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, messageID);

This diagnostic is classified as:

CWE-190 CERT-INT02-C

You can look at examples of errors detected by the V673 diagnostic.