CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Show me the signs! Signed vs unsigned... when exactly does

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
s_mack



Joined: 04 Jun 2009
Posts: 107

View user's profile Send private message

Show me the signs! Signed vs unsigned... when exactly does
PostPosted: Sun Sep 06, 2009 4:56 pm     Reply with quote

Say I have this:
Code:
if ( delta_u_n < (u_min - u_n_1) )


if delta_u_n is a signed int but the other two are both unsigned, could I run into a problem? If u_min - u_n_1 produces a negative number but are both unsigned does that mean the result of that little bit of math is still positive? Thereby forcing the statement to always be false if delta_u_n is negative? Or is it implicitly converted to signed at the < first ??

I read the help file regarding this but I'm still not sure.

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Sep 06, 2009 5:55 pm     Reply with quote

Make a test program. Use printf to show the results. See the example
at the end of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=28867
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 1:07 am     Reply with quote

It's generally a good idea to check the compiler behaviour empirically.

The other interesting question is however, if there's an expected result according to C language rules, and in addition, if CCS C is following the rules in this case. This question is particularly interesting for those, who are working also with other tools besides CCC C.

As far as I know, clear rules exist for the present case, and they are basically identical for K+R and ANSI C:

- implicite type conversion applies for relational operators
- when signed and unsigned operands of same word length are used together, the signed operand shall be converted to unsigned

This expected behaviour can be found with full featured C compilers, e.g. from Microsoft or Borland.

As far as I see, CCS C is following different "rules". With PCH, the compare is performed without implicite type conversion. Thus when comparing an unsigned with a negative signed value, the negative value is always regarded smaller. This result may be expected by common sense, but is not according to C rules.

With PCD, an implicite type conversion from unsigned to signed is performed, also contradicting usual C rules.

As a result, explicite type conversions should be used with CCS C in mixed type expressions to clarify your intentions. It doesn't harm with other C compilers anyway.

Code:
if ( delta_u_n < (signed int16)(u_min - u_n_1) )
s_mack



Joined: 04 Jun 2009
Posts: 107

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 1:11 am     Reply with quote

Thanks!
Ttelmah
Guest







PostPosted: Mon Sep 07, 2009 3:17 am     Reply with quote

The difference here, is actually in the C language!...

If you read A6.5, in K&R, the 'rules' for converting signed/unsigned, depend on whether the 'signed' type, can represent all values contained in an unsigned type:

"The effect depends on whether a long int can represent all values of an unsigned int; If so, the unsigned int, is converted to long int; If not, both are converted to unsigned long int.".

So, Given that the signed type in CCS, only has 15 bits for the actual value, CCS is correct to convert both values to unsigned, and compare with these.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 4:15 am     Reply with quote

In my opinion, the K&R remark on unsigned short to long int conversion only applies, when long int is one of the involved types. It isn't in the present case. So the general rule of converting to unsigned (unsigned int16 in this case) applies. In my understanding the ANSI C type conversion rules are basically telling the same, but I'm not very familiar to it.

So if PCH would use general C conversion rules, an explicite typecast to signed int16 is necessary to achieve the intended behaviour.

The other point is, that according to my test, neither PCH nor PCD (V4.099) are following the rule. But the typecast is correct for CCS C anyway.
Ttelmah
Guest







PostPosted: Mon Sep 07, 2009 5:05 am     Reply with quote

I don't agree.
The very next line says:
"Otherwise if either operand is unsigned int, the other is converted to unsigned int.".

What is left unsaid, is 'how' the conversion should be done....

For myself, the best way to work, is to be completely 'explicit' in your testing, and not assume anything about the language. So if comparing signed, with unsigned, test your signed value for being less than zero, and do your own handling of this potential 'overflow' situation, or explicitly use a larger type.

Best Wsihes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 8:50 am     Reply with quote

Quote:
What is left unsaid, is 'how' the conversion should be done....

In my K&R version, it's defined as 2^nbit modulo operation, in other words taking the signed bitvector as unsigned. That's also, what most C compilers do.

But I completely agree to your conclusion, that explicite typcasting is the preferable, safe method.
s_mack



Joined: 04 Jun 2009
Posts: 107

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 11:23 am     Reply with quote

i understand that it is best to just be explicit. The problem I see is the extra logic required to handle potential overflow adds to the program size and we're working in embedded applications with almost necessarily finite ROM. So understanding how "shortcuts" may work can be critical to reducing the size.

In my case this time, what happened was because of the math involved I needed a ton of code to account for the various overflow possibiities. In the end it was more efficient to eliminate all that and use all signed int32 instead. This seemed very unfortunate because I spent a lot of effort converting all my floats to int16 only to have them be int32 just because of signs kind of sucked.
s_mack



Joined: 04 Jun 2009
Posts: 107

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 12:35 pm     Reply with quote

Somewhat unrelated (nothing to do with signs)
Code:
pedal_output = (int8)(( pedal_setting + 64 ) >> 7);


Assume pedal_setting is an int16 and pedal_output is an int8. "when" does the typecast happen? Is it at assignement or before the math? Should I just leave the int8 out and let the = handle that?

The intent here is to add 64 to my int16 value then divide that by 128 (which by previous math guarantees it is < 255) and assign the result as an int8 to pedal_output.

Have I done it right? Or should it be more (or less?) explicit?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 07, 2009 1:24 pm     Reply with quote

I think, it's O.K. this way.

The brackets specify to apply the (int8) typecast after all arithmetic, which is obviously intended. It shouldn't be necessary because the assignement to an int8 variable basically does the same. However some compilers issue warnings about possibly lost bits in assignment and the type cast would be an appropriate means to suppress the warning.

I experienced a curiosity with CCS C, that type casts sometimes involve generation of additional (meaningless) code. If you are short on resources, you may want to check the impact of this constructs on code size.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group