lowByte and highByte are not really byte functions

The reference page states that lowByte and highByte return a byte. This appears not to be the case.

I discovered this when making a call like:

Wire.send(lowByte(i2cdata));

if i2cdata is type int, this works fine. If i2cdata is type word, a compiler error is generated.

I am not sure exactly why but I suspect it has to do with the way lowByte and highByte are implemented in Wiring.h:

#define lowByte(w) ((w) & 0xff)
#define highByte(w) ((w) >> 8)

so what type you get from highByte and lowByte depends on what you feed them.

You can easily fix this by using (byte)lowByte(xxxx) but it is cetainly counter-intuitive.

To show this more clearly:

void setup() {
  
int d, c, a = 0xffff;
byte b;

Serial.begin(9600);

b = lowByte(a);
c = sizeof(b);

d = sizeof(lowByte(a));

Serial.print(c,DEC);
Serial.print(" ");
Serial.println(d,DEC);

}

void loop(){}

produces the output:

1 2

showing that with an int argument lowByte returns an int value.

C essentially specifies that all intermediate values in calculations are of at least type 'int', which occasionally causes assorted problems with attempts at optimization. But I'm not sure why "Wire.send(lowByte(i2cdata));" would cause a compiler error (what's a "word"?); aren't arguments automagically truncated to correct size?