The compiler will not detect any error and the code will compile and execute. Hence, to see what happens we need to explore the behind-the-scenes magic. For a summary, skip to end.
The second line in your code is where the magic will happen and thats where we need to focus.
pinMode(pin, OUTPUT);
The portion of pinMode
relevant to this discussion is:
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin); //The first instance where pin is used
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return;
//Do something
}
(The complete implementation can be found in wiring_digital.c)
So, here, digitalPinToBitMask
seems to be using pin
to compute an intermediate bit. Exploring further, digitalPinToBitMask
is a macro defined in Arduino.h
whose definition is this one-liner:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
This weird looking one liner does a very simple task. It indexes the Pth element in the array digital_pin_to_bit_mask_PGM
and returns it. This array digital_pin_to_bit_mask_PGM
is defined in pins_arduino.h
or the pin map for the specific board being used.
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(0), /* 0, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
...
};
This array has 20 elements in total, so we are out of luck. 999 will index a memory location in the flash memory outside of this array, thereby leading to unpredictable behavior. Or will it?
We still have another line of defense against runtime anarchy. Its the next line of the function pinMode
:
uint8_t port = digitalPinToPort(pin);
digitalPinToPort
takes us along a similar path. It is defined as a macro along with digitalPinToBitMask
. Its definition is:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Now, we index the Pth element of digital_pin_to_port_PGM
which is an array defined in the pin map:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
This array contains 20 elements, so 999 is again out of range. Again, this command reads and returns a value from flash memory of whose value we cannot be certain. This will again lead to unpredictable behavior from here on.
There is still one last line of defense. That is the if
check in pinMode
on the return value of digitalPinToPort
:
if (port == NOT_A_PIN) return;
NOT_A_PIN
is defined as 0 in Arduino.h
. So, if the returned byte from digitalPinToPort
happens to be zero, then pinMode
will silently fail and return.
In any case, pinMode
cannot save us from anarchy. 999 is destined to result in doom.
TL;DR, the code will execute and the result of this will be unpredictable. Most likely, no pin will be set to OUTPUT
, and digitalWrite
will fail. If you happen to have exceptionally bad luck, then a random pin may get set to OUTPUT
, and digitalWrite
may set it to HIGH
.