Implicit arithmetic conversion

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

Implicit arithmetic conversion

Jump to solution
3,218 Views
WHookway
Contributor III

Hello,

 

I have the following code:

 

unsigned char xx;

 

xx |= 4;             No conversion errors

 

xx = xx | (unsigned char)4;          Generates implicit arithmetic conversion from 'int' to 'unsigned char'

 

Compiling for the 51JM128.

It appears as if the unsigned char is being treated as a int regardless of the cast.

In the C/C++ compiler settings I have the Use Unsigned Chars check box checked.

I'm using the CW IDE 5.9.0, build 5292.

I do not want to turn off the Implicit Arithmetic Conversions warnings globally.

Why can't this error be explicitly cast away?

 

Thanks,

Will

Labels (1)
0 Kudos
Reply
1 Solution
1,150 Views
kef
Specialist I

xx = xx | (unsigned char)4;          Generates implicit arithmetic conversion from 'int' to 'unsigned char'

 

first you typecast 4 to uchar, then xx and uchar==4 are promoted to int, then | is performed, then implicit convertion of int result to uchar xx takes place. Try typecasting result of |.

View solution in original post

0 Kudos
Reply
6 Replies
1,151 Views
kef
Specialist I

xx = xx | (unsigned char)4;          Generates implicit arithmetic conversion from 'int' to 'unsigned char'

 

first you typecast 4 to uchar, then xx and uchar==4 are promoted to int, then | is performed, then implicit convertion of int result to uchar xx takes place. Try typecasting result of |.

0 Kudos
Reply
1,150 Views
WHookway
Contributor III

Thank you,  looking at the assembly manual I see the OR operation only can operate on a longword.  I understand, it may  end up with a bunch of casting since I am porting an application over.

Regards,

Will

 

 

0 Kudos
Reply
1,150 Views
kef
Specialist I

It has nothing to do with longword only OR instruction or other architecture specifics. C integer promotion rules take place even in compiler for 8 bit machines. All integer arguments of +-/*&|.. are first promoted to int type. Size of int is target specific.

 

unsigned char xx;

 

xx = xx | (unsigned char)4;

 

(unsigned char) typecast before |-operation makes no sense, because before | (unsigned char)4 will be promoted back to integer. In fact it is the same to 

  

   xx = xx | (int)(unsigned char)4;

 

To suppress warning try this

 

xx = (unsigned char)(xx | 4);

 

xx still will be promoted to int, then int==xx will be ORed with int==4, and then not implicit, but explicit (unsigned char) typecast will be performed and result will be saved to xx without warning.

 

0 Kudos
Reply
1,150 Views
WHookway
Contributor III

You might be right about this specific processor, but I'll bet that it (32 bit architecture) played a role in the decision.  Not all compilers handle the promotion the same.  If the compiler recognizes the operation is on a unsigned char then it may not be promoted to the architecture int size as you suggest.  Try examining disassembled code from other vendors and you will observe what I am talking about.  If this is a convenience, optimization or a departure from the 'C' standard I can't say, but the result is the team of software developers have come to rely on it, and now we will be forced to edit the code with a bunch of casting.  Anyhow, your suggestion in your first post was on target and casting the result of the | worked, this is why I responded that a solution had been found.

Regards,

Will

 

0 Kudos
Reply
1,150 Views
CompilerGuru
NXP Employee
NXP Employee

>You might be right about this specific processor, but I'll bet that it (32 bit architecture) played a role in the decision. 

I don't so, you probably would loose this bet. It only matters that the size of an int is bigger than the size of a char, and that's the case on most architectures (not on all).

 

> Not all compilers handle the promotion the same.

All ANSI-C compilers handle the promotion the same.

 

>  If the compiler recognizes the operation is on a unsigned char then it may not be promoted to

> the architecture int size as you suggest.

It is per language always promoted. Always.

This does not mean however that any compiler will end up generating code which does use int's in the generated code, if the result is the same as if the operation was done with smaller types, then all compilers I know will use smaller types if this is preferable.

From a language point of view this is already an optimization.

 

>  Try examining disassembled code from other vendors and you will observe what I am talking about.

The warning is not about the generated code at all, it is about the types being used. Looking at the generated code therefore does not show the issue the compiler warns about.

 

>  If this is a convenience, optimization or a departure from the 'C' standard I can't say

It's neither of those. The compiler simply states that an int is assigned to a unsigned char.

 

>, but the result is the team of software developers have come to rely on it, and now we will be forced to edit the code with a

> bunch of casting.  Anyhow, your suggestion in your first post was on target and casting the result of the | worked,

> this is why I responded that a solution had been found.

 

I think issue you have is that the compiler warns (technically correctly) about something which he could know that it is not an issue in this case after all. While it is correct that an int gets assigned to a unsigned char, the compiler could deduce that in this particular case all of the bits of the int which do not fit into the destinations unsigned char are indeed 0's. So the assignment cuts the type, but it does not cut any possible value.

 

When I tried the sample with the CF V1 compiler in mcu 10, I did not get the warning, maybe this unnecessary warning case has already been addressed in the compiler :smileyhappy:

 

Daniel


0 Kudos
Reply
1,150 Views
WHookway
Contributor III

Daniel,

I was under the impression that I was limited to CW 6.3 or earlier for the MCF51JM128, since all the references seemed to point to this version (and still do for the MCF51JM128).  It appears as if CW 10 supports this part, MQX and the CMX stack for USB then I will do my evaluation with this compiler.

Thanks,

Will

 

 

0 Kudos
Reply