Int to byte


I have a library where it reads from an external eeprom and it returns a character as a int but it is supposed to be a byte. How would you convert how would I convert the int to a byte?

char_variable = (char) int_variable;

char_variable = (char) int_variable;

I think you misplaced the parentheses.

I think it should be this: char_variable = char(int_variable);

The char function in the Arduino core is a crutch for people who are not comfortable using casts.

Your way produces exactly the same results as fdufnews’.

It does[ch8253]*

I’m not a very advanced programmer, but I thought that parentheses were to indicate the parameters of a function?
I think I just misunderstand fdufnews’s code, could you explain?

*interrobangs are fun

In C/C++, variables have types. There are some explicit conversions that are performed when converting one type to another. These are performed only when the conversion can not result in a loss of data. For example:

int myInt = 49;
long myLong = myInt;

The reverse conversion will generate a compilation error:

long myLong = 69032;
int myInt = myLong;

The error occurs because 69032 will not fit in an int.

But, what happens when the value in myLong will fit in myInt?

long myLong = 32;
int myInt = myLong;

The same compilation error occurs. This happens because the compiler is not looking at the value in the variable, which might change at run time.

If you KNOW that myLong will never contain a value that will not fit in myInt (or you don't care), you can tell the compiler that you are willing to accept a potential loss of data by casting.

myInt = (int)myLong;

This format, with the variable type inside parentheses, is known as a cast.

Since this looks strange to non-programmers, the Arduino folks added some functions (int(), char(), etc.) that internally perform the cast, hiding the strange syntax.

Converting from one basic type to another is not where casts are really useful, though. When you start getting into classes with multiple inheritance, it's nice to write a function that takes a pointer to the base class as input and/or returns a pointer to the base class.

Since a pointer to a base class can not normally be stored in a variable whose type is pointer to a derived class, casting becomes very useful.


The reverse conversion will generate a compilation error:

long myLong = 69032;
int myInt = myLong;

In fact, those statements do not generate compiler errors. (In fact, they wouldn't even generate compiler warnings with avr-gcc if warnings were not suppressed by Arduino.) If the value of the expression on the right of the assignment statement is too large to be represented as the type of variable on the left, the value is silently truncated (upper bits are thrown away). The compiler will not (and according to the C++ Standard, can not) treat implicit type conversions like this as an error.

It is the programmer's responsibility to know if and when assignments to different integer data types can cause the program to "misbehave."

Arduino folks added some functions (int(), char(), etc.)

No they didn't. The identifiers int and char are keywords. You couldn't create a function named char() even if you wanted to.

To sciguy: The notation char(whatever) is defined in C++ (not in C) to designate "Explicit type conversion" using functional notation. It looks like a function call, but has the same effect as using a cast in the old-fashioned C way (with the type in parentheses before the identifier). Some C++ programmers turn their noses up at the old-fashioned notation for various reasons. Some of them are actually good reasons that we don't need to go into here. (For me, the real bottom line comes after "However...")


To the Original Poster (and everyone else): It is not necessary to use a cast when assigning one integer data type to another. If you want to to use a cast to make sure that human readers know that you know that the assignment is from a different data type, that's OK but it's not necessary. See Footnote.

My problem is this: I don't know what you mean by saying that you have a library function that "returns a character as an int but is supposed to return a byte."

The person who wrote the function certainly knows what it is "supposed to return." Sometimes library functions return characters as integer values so that in case of some special condition the function can return an integer value that can't be expressed as a byte. So the person writes the function so that in case of an error it returns an integer value of -1. For 16-bit ints that are used with our CPUs, that is a hexadecimal value of 0xffff.

The calling function checks to see whether the returned integer value is equal to -1. If it is, then there was an error of some kind, otherwise the calling program uses the byte value wherever it needs to. If the calling function cavalierly converts the int return value to a char without checking first, then it doesn't distinguish between an authentic char value 0xff (which would be returned as the integer 0x00ff) and the special case integer value 0xffff.



Footnote: Sometimes people use casts to suppress certain compiler warnings or even error messages, when what they should have done was to find out why the message was generated and correct the code. I have been in design reviews where C++programs filled with loads of superfluous casts were rejected because some of the casts were used to suppress meaningful warnings, and the reviewers just didn't feel like going through all of them to decide which casts were unnecessary (and, in principle, benign) and which casts were indicators of real problems.

The "Big Boss," who had more experience than everyone else in the room (all put together) stated that superfluous casts were a red flag, and a big indicator that the programmer really didn't know what he was doing. I consider that kind of harsh, but I still get nervous when I see unneeded casts sprinkled around the landscape with no indication (in comments) of why the cast is being used. Sometimes they are necessary, but "usually" not.