left shift count >= width of type in C macro

how to calculate left shift
left shift operator
left shift neutrophils causes
left shift percentage
left shift 32 bits
left shift vs right shift cbc
what is left shift on keyboard
shift to the left economics

I have written a C Macro to set/unset Bits in a uint32 variable. Here are the definitions of the macros:

extern uint32_t error_field, error_field2;
    #define SET_ERROR_BIT(x) do{\
                                if(x < 0 || x >63){\
                                    break;\
                                }\
                                if(((uint32_t)x)<32U){\
                                    (error_field |= ((uint32_t)1U << ((uint32_t)x)));\
                                    break;\
                                } else if(((uint32_t)x)<64U){\
                                    (error_field2 |= ((uint32_t)1U<<(((uint32_t)x)-32U)));\
                                }\
                            }while(0)

    #define RESET_ERROR_BIT(x) do{\
                                if(((uint32_t)x)<32U){\
                                    (error_field &= ~((uint32_t)1U<<((uint32_t)x)));\
                                    break;\
                                } else if(((uint32_t)x) < 64U){\
                                    (error_field2 &= ~((uint32_t)1U<<(((uint32_t)x)-32U)));\
                                }\
                             } while(0)

I am passing a field of an enumeration, that looks like this:

enum error_bits {
    error_chamber01_data = 0,
    error_port21_data,
    error_port22_data,
    error_port23_data,
    error_port24_data,
/*this goes on until 47*/
};

This warning is produced:

left shift count >= width of type [-Wshift-count-overflow]

I am calling the Macros like this:

USART2->CR1 |= USART_CR1_RXNEIE;
SET_ERROR_BIT(error_usart2);
/*error_usart2 is 47 in the enum*/
return -1;

I get this warning with every macro, even with those where the left shift count is < 31.

If I use the definition of the macro without the macro, it produces no warning. The behaviour is the same with a 64 bit variable. I am programming a STM32F7 with AC6 STM32 MCU GCC compiler. I can't figure out why this happens. Can anyone help me?

Probably a problem with the compiler not being able to diagnose correctly, as stated by M Oehm. A workaround could be, instead of using the minus operation, use the remainder operation:

#define _SET_BIT(x, bit) (x) |= 1U<<((bit) % 32U)
#define SET_BIT(x, bit) _SET_BIT(x, (uint32_t)(bit))
#define _SET_ERROR_BIT(x) do{\
                            if((x)<32U){\
                                SET_BIT(error_field, x);\
                            } else if((x)<64U){\
                                SET_BIT(error_field2, x);\
                            }\
                        }while(0)
#define SET_ERROR_BIT(x) _SET_ERROR_BIT((uint32_t)(x))

This way the compiler is finally smart enough to know that the value of x will never exceed 32.

The call to the "_" macro is used in order to force x to always be an uint32_t, inconditionally of the macro call, avoiding the UB of a call with a negative value of x.

Tested in coliru

warning: left shift count >= width of type, So, i'm getting the titled error message: left shift count >= width of type [-Wshift-​count-overflow] My program seems to compile and run fine, but i  What Is a Shift to the Left in Blood Testing? Calculations. The total percentages of the differential (the percentage amount of each type of cell) must add up to 100%. The Shift. White Blood Cells. White blood cells vary in number because they are part of the immune system of the body. Some

Problem:

In the macros, you distinguish two cases, which, on their own, are okay. The warning comes from the branch that isn't executed, where the shift is out of range. (Apparently these diagnostics are issued before the dead branch is eliminated.) @M Oehm

Solution

Insure shifts are in range 0-31 in both paths regardless of the x value and type of x.

x & 31 is a stronger insurance than x%32 or x%32u. % can result in negative remainders when x < 0 and with a wide enough type.

   #define SET_ERROR_BIT(x) do{\
                                if((x) < 0 || (x) >63){\
                                    break;\
                                }\
                                if(((uint32_t)x)<32U){\
                                    (error_field |= ((uint32_t)1U << ( (x)&31 )));\
                                    break;\
                                } else if(((uint32_t)x)<64U){\
                                    (error_field2 |= ((uint32_t)1U<<( (x)&31 )));\
                                }\
                            }while(0)

As a general rule: good to use () around each usage of x.

Left shift count >= width of type [-Wshift-count-overflow], By default, integers are 16-bit (doesn't matter what the target type is on the LHS) so trying to shift 1 left by 16 bits would result in zero. Use 1L <<  Because our writing is recorded from left to right, when the neutrophil count is increased, it became known as a left shift. The Wrap Up When you get your blood tested, there are three main counts that doctors look at: red blood cells, white blood cells and platelets.

warning: left shift count >= width of type, It's basically an inability of the compiler to auto-promote the source variables to a size big enough to fit the shifted version. The default type for  You can't shift a value to its max bit. int x; // let int be 4 bytes so max bits : 32 x <<= 32; So, this generates the warning . left shift count >= width of type (i.e type = int = 32 )

Bit shifting fails with warning: left shift count >= width of type , The code shown, however, might give this compile warning unexpectedly. Sure, a 1 shifted 63 times up will fit in a 64-bit int. But the 1 itself must be 64 bit as well:​  Left shift. A left shift indicates the presence of immature neutrophils in blood and usually, but not always, indicates an inflammatory leukogram (see related links for the historical origin of this term). Immature neutrophils are usually band neutrophils, but earlier forms can be seen. A few to no band neutrophils are seen in the blood of clinically healthy animals we use for establishing our reference intervals.

left shift count >= width of type, Compiler warning: left shift count >= width of type. Log in or I think you need to cast typ and geraet to unsigned long before the shift. Shifting  The term left shift means that a particular population of cells is shifted towards more immature precursors (meaning that there are more immature precursors present than you would normally see). Take the neutrophil series, for example.

Compiler warning: left shift count >= width of type, warning: left shift count >= width of type [-Wshift-count-overflow] with 1, problem is with shifting it by 32 bits. uint64 is treated as 32 bit value. Neutrophil left shift and white blood cell (WBC) count are routine laboratory tests used to assess neutrophil state, which depends on supply from the bone marrow and consumption in the tissues. If WBC count is constant, the presence of left shift indicates an increase of neutrophil consumption that is equal to an increase of production.

Comments
  • show where the macro is called also
  • I have edited the post.
  • This (and I really don't mean to cause offence here) truly hideous beast is a classic example of why macros are a bad idea for anything other than simple true/false things in modern C compilers. You could write something far more readable with a function that generally has little performance impact, if any. I always try to optimise for readabilty first :-)
  • I already thought of writing a function for this, but i want to figure out why the warning is produced
  • In the macros, you distinguish two cases, which, on their own, are okay. The warning comes from the branch that isn't executed, where the shift is out of range. (Apparently these disgnostics are issued before the dead branch is eliminated.)
  • This works fine for numbers <32. For numbers >=32 it produces the same warning: coliru.stacked-crooked.com/a/3d79a452e4a6efda
  • yes, because the other branch needs also the modulus operation, I update the link
  • I have also simplified the macro, removing unnecessary castings and breaks
  • I figured out the fault, see the last comment. Thank you!
  • Yes, with -1LL that is true, did not see that. Still hole remains, but in a new, and less likely, place such as SET_ERROR_BIT(-0x100000000) as the (uint32_t) cast simply wraps the negative values and then some will end up as 0-63.
  • OP's code handled x < 0. This answer, like first one, has vulnerability when x < 0.
  • It's not a vulnerability to avoid the x<0 control, because the input variable should be considered an unsigned at compilation time. If you use an int the code will be compiled with error. If you force the variable at a negative value the code will consider the value as a number greater or equal to 0, so it is sufficient to consider the control on greater than 63.
  • Disagree with "because the input variable should be considered an unsigned at compilation time". Enumerated values are not certainly unsigned ref and OP wisely wants to prevent possibility with if(x < 0
  • In the code I've implemented the variable x is an unsigned. May be I'm OT.