Can I use 1-byte datatypes to store digital input?

I am reading the docs on DigitalRead() and wondering why it stores seemingly boolean `HIGH` and `LOW` inputs in `int` data type variable.

I have two issues with that:

1. `int` is 2-byte, while `bool` and `uint8_t` are 1-byte so it seems like a waste of memory for no benefit whatsoever.
2. It gets me confused when reading the code about whether the input came from digital or analog since `int` can have a wide range.

Is there any particular reason for storing digital inputs as `int`?

EDIT: `bool` and `uint8_t` are out of the question as per the answer below. `int8_t` still looks suitable for the purpose though.

• Note that the value returned by a function is passed in internal CPU registers, so no waste of RAM here. If I ever had to store the returned value in memory, I would indeed use an `uint8_t`. – Edgar Bonet Mar 4 '20 at 8:37

You receive the data as `int`, but you store it as `byte`.

For example, when you call the serial library function to receive a data byte, the library will return either the data or a -1 if a problem has occurred.

The binary value of -1 is a byte 11111111 or int 1111111111111111.

The binary value of 255 is a byte 11111111 or int 0000000011111111.

I think that you can see the problem if you use `byte` data and the data is 255.

So, if you receive an `int` -1, then you do not process the data. Otherwise you `cast` the `int` to `uint8_t`.

You could receive `byte` data, but then the value of 255 would be undefined.

• I suspected there was something hidden going on. What about `int8_t`? It can store -1, 0, and 1 and still takes up 1 byte – Arthur Tarasov Mar 4 '20 at 5:14
• `int8_t` stores values of -128 to 127 .... `uint8_t` stores values of 0 to 255 ... the two data types both store 8 bits ... they are just there so that the compiler will throw a warning if the limits are exceeded – jsotola Mar 4 '20 at 5:36
• So I just replaced all `int`s storing digital inputs in my program with 1-byte `int8_t`s. It seems to work fine so far. – Arthur Tarasov Mar 4 '20 at 5:49
• Neither `digitalRead()` nor `analogRead()` ever return `-1`. There is no reason why `digitalRead()` is a `int` function instead of `uint8_t`, and it indeed needlessly wastes space. The compiler will probably optimize it away though, if you store the result as `uint8_t` or `int8_t` – towe Mar 4 '20 at 10:31

I did not check the internals a while, but in early days there was a

`````` #define HIGH 1
``````

meaning that HIGH is a `const int`.

Perhaps someone did not want to disable some TRI-STATE digital logic in the beginning, and since then nobody wanted to change the basics.

But of course `bool` is a more appropriate data type for HIGH/LOW and of course you can always treat them this way, for example like

``````if (! digitalRead(pin) ) { // pin is LOW
...
}
``````

jsotola's answer why Serial.read() returns an `int` is a different issue. And correct of course.

The smallest unit in most languages is a byte (8 bits), whether signed or unsigned. So returning a byte, even if it only returns three different values, is the smallest and most efficient unit available, that I'm aware of.

If you want to store later, you can assign each bit of a byte as a high or low, thus giving you 8 storage spots.

One could always store the value of digitalRead() as a bit in a variable, compacting the data from say 8 pins down into 1 byte

``````// read an input and store it, say the reads of D2 thru D9 are stored in byte bits9to2
// 9,8,7,6,5,4,3,2
// first clear the state for 2
bits9to2 = bits9to2 && 0b11111110; // two && for bit manipulation? Or just 1?
// then map in the new value
bits9to2 = bits9to2 || 0b00000001;// two || for bit manipulation? Or just 1?
}
else{
// leave it as 0
}
``````

Then to use it later on:

``````if ((bits9to2 && 0b00000001) != 0){
// bit is set (HIGH), do whatever
}
else {
// bit is clear (LOW), do whatever, or maybe do nothing
}
``````

Can use an unsigned int and store 16 bits compacted that way, or unsigned long for 32 bits.