Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Long, Int, Char

Status
Not open for further replies.
If I'm doing math with different variable types, can I run into trouble? For example, if I'm doing:

A = B * C; or
A = B / C;

If A is a long, and B and C are a char and an int, is it possible to get the wrong result because I mixed variable types? (Assuming I've done my due diligence, i.e. B * C < 2^32)

Is this considered poor practice? Is it best to cast them all as longs before performing these operations? Thanks!
 
You can mix variable types and your results will be accurate provided you *know* you will never have a result bigger than that variable can handle. If you have the speed and RAM to spare it doesn't hurt much to up the variable size to be on the safe side. It's not often we have that luxury though, code space and RAM are a premium on most projects.
 
Types will be promoted, so A=B*C will be equivalent to A=(long)((int)B*C) - so B will be promoted from char to int during the multiplication, and the result promoted to long at the assignment.

Casting is almost ALWAYS wrong - don't do it unless you REALLY know what you're doing. Basically, if you need to ask if you should cast, the answer is NO YOU SHOULDN'T. When you don't need to ask because you know what'll happen, that's when you can. If you need a cast, the chances are that you used the wrong type. There's an example of wrong type use in the above, why are you using a char in a numeric expression? Chars are for character data, nothing else. They are not for storage of numbers from 0-255; use an unsigned short for that.
 
I would suggest getting rid of the old class names and use the stdint.h types (int8_t, uint8_t, int16_t, unint16_t...) If your compiler isn't C99 compliant you should be able to make or borrow your own stdint.h include.
 
Types will be promoted, so A=B*C will be equivalent to A=(long)((int)B*C) - so B will be promoted from char to int during the multiplication, and the result promoted to long at the assignment.

Casting is almost ALWAYS wrong - don't do it unless you REALLY know what you're doing. Basically, if you need to ask if you should cast, the answer is NO YOU SHOULDN'T. When you don't need to ask because you know what'll happen, that's when you can. If you need a cast, the chances are that you used the wrong type. There's an example of wrong type use in the above, why are you using a char in a numeric expression? Chars are for character data, nothing else. They are not for storage of numbers from 0-255; use an unsigned short for that.

This may be true in the PC world but this is the microcontroller section and in the uc world chars are used to store numbers from 0 to 255. Also, automatic promotion isn't guaranteed. In fact the Microchip C18 compiler defaults to byte size operations unless you specifically cast. Doing int temp=10*60; will leave temp containing 88 :eek: which is why I avoid C18.

Mike.
 
This may be true in the PC world but this is the microcontroller section and in the uc world chars are used to store numbers from 0 to 255. Also, automatic promotion isn't guaranteed. In fact the Microchip C18 compiler defaults to byte size operations unless you specifically cast. Doing int temp=10*60; will leave temp containing 88 :eek: which is why I avoid C18.

Mike.

Which is why there is a option to default promote to 'int'.
MPLAB IDE calculation bug

A few things I learned a long time ago not to do.

1. Depend on variable promotion. Use explicit casts.
2. Depend on the parser to determine order of operations. Use parentheses (a lot)
 
1. Depend on variable promotion. Use explicit casts.
2. Depend on the parser to determine order of operations. Use parentheses (a lot)

Would you explicitly cast B and C in the example equation then?
A = (long)B * (long)C;

Or is it better to define B and C as long if they will be used somewhere in the program in a calculation with a long?
 
Last edited:
Would you explicitly cast B and C in the example equation then?
A = (long)B * (long)C;

Or is it better to define B and C as long if they will be used somewhere in the program in a calculation with a long?

If it's possible the values in the equation could overflow either of the lesser variable types then casting both long is wise from the point of being robust. As others have said, 'better' is best determined on what you need at the time, if it's in a ISR and the data has fixed restraints (0..255) then smaller data sizes could be faster.
 
Which is why there is a option to default promote to 'int'.
MPLAB IDE calculation bug

A few things I learned a long time ago not to do.

1. Depend on variable promotion. Use explicit casts.
2. Depend on the parser to determine order of operations. Use parentheses (a lot)
I know about the option and was really replying to the statement "Casting is almost ALWAYS wrong" as this statement is almost ALWAYS wrong when it comes to uC.

However, I also wanted to point out what I consider a serious bug in C18 but Microchip think is fine. Namely, the following two lines are not equivalent.
Code:
int temp=10*60;   //temp will contain 88
int temp=600;      //temp will contain 600
To limit the size of constants at compile time (whilst done on the PC) is, IMHO, a very bad decision. I wonder how many times that has bitten a programer.

Mike.
 
One thing the OP failed to do after we told him in chat WAS to start a clear understanding new thread so he could get help. As he hasn't responded since he made the thread he is using Pic Basic Pro and not 'C'. Had I seen this new thread last night I would of edited it to show he was using PbP as not to confuse members but unfortunately that is what has happened.

It really make me wonder with the youth of today if a few of the important DNA strings are missing and being clear and concise is from a bygone era.......

Regards Bryan
 
However, I also wanted to point out what I consider a serious bug in C18 but Microchip think is fine. Namely, the following two lines are not equivalent.
Code:
int temp=10*60;   //temp will contain 88
int temp=600;      //temp will contain 600
To limit the size of constants at compile time (whilst done on the PC) is, IMHO, a very bad decision. I wonder how many times that has bitten a programer.

Mike.

"It's not a bug, it's a feature"

I hear you, but I'm sure there's code libraries that relies on this Non Ansi C behavior for short cut access to hardware functions on different processors. I have a habit of just pre-computing initializations anyway and adding a comment about it.
 
Last edited:
One thing the OP failed to do after we told him in chat WAS to start a clear understanding new thread so he could get help. As he hasn't responded since he made the thread he is using Pic Basic Pro and not 'C'. Had I seen this new thread last night I would of edited it to show he was using PbP as not to confuse members but unfortunately that is what has happened.

It really make me wonder with the youth of today if a few of the important DNA strings are missing and being clear and concise is from a bygone era.......

Regards Bryan

I should have been clear when I started the post: I am coding in C using the MSP430 with Code Composer Studio. I thought it was a generic question about C programming, but clearly it depends on the compiler.
 
FYI, C18 is the only compiler I have come across that doesn't promote chars to (16 bit) integers and there is a command line switch to fix it.

Mike.
 
Status
Not open for further replies.

Latest threads

Back
Top