Shift count converted to unsigned char

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Shift count converted to unsigned char

1,751 Views
Lundin
Senior Contributor IV

I'm running this code:

 

uint16_t bit_n; ...  uint16_t mask = 1u << bit_n%8;

 

No matter which Codewarrior version I'm using, I'm getting this warning/"info": C4003 Shift count converted to unsigned char.

 

What is this nonsense? See the standard for the shift operators C11 6.5.7: "The integer promotions are performed on each of the operands.". No matter if int happens to be 16 or 32 bit on my particular platform, there is no way the shift count should be unsigned char. First of all it is already of a type larger than char. And regardless of that, it must always be integer promoted. Furthermore, the right operand of the shift in this specific case must already be int, as it was already implicitly promoted to that type by the % operator.

 

Questions:

1. Why isn't Codewarrior following the C standard? Is this some non-standard optimization for small MCUs (HCS08 etc)? Or just a bug?

2. Why is Codewarrior warning me about it? As far as I'm aware, I never told Codewarrior to deviate from the standard.

 

I actually don't care about what type the right-hand operand has, as long as the result is correct. But I'm following this coding standard which is stating that the project must be 100% compliant to ISO C and free of compiler warnings.

Labels (1)
Tags (2)
0 Kudos
Reply
3 Replies

986 Views
BlackNight
NXP Employee
NXP Employee

Hi Daniel,

You are right with the rule you quote here. And the compiler is right too: the compiler can internally optimize this to any level as long the result is conforming to the standard. The standard does not specify the way to get the result, but describes what the (end) result shall be.

For your questions:

1) The compiler is following the standard, it is just verbose here about what it is doing. So no bug.

2) You can switch/suppress any (well, most) messages. If you are not interested in this one, you can use the compiler option -WmsgD4003 to turn it off.

I hope this helps,

Erich

0 Kudos
Reply

986 Views
Lundin
Senior Contributor IV

The compiler is only allowed to optimize the code if it can deduct that the behavior of the program is unaffected and that no side effects are optimized away. CW still gives me the warning when I declare the "bit_n" variable as volatile. So I assume it is optimizing my volatile variable as well, in which case it is definitely a bug.

Suppose the uint16_t was a hardware register on an 8 bit MCU, that needs to have both its ms and ls byte read, because of internal hardware in the hardware peripheral. A situation not too uncommon on for example the Freescale HCS08 family (timer registers, ADCs etc). Then code like

uint16_t adc_read = 1u << ADC_DATAREG;

would give incorrect results, because CW would generate code that only reads half of the 16 bit register, while the Freescale hardware requires that both bytes of that register must be read.

0 Kudos
Reply

986 Views
Lundin
Senior Contributor IV

Silence.

Does CW often optimize volatile variables or is it just in this specific case? And if it does optimize volatile variables, how then does the compiler conform to the very core of the C standard, chapter 5.1.2.3 "Program execution" (C99/C11)?

0 Kudos
Reply