O compilador não detectará nenhum erro e o código será compilado e executado. Portanto, para ver o que acontece, precisamos explorar a mágica dos bastidores. Para um resumo, pule para o final.
A segunda linha do seu código é onde a mágica acontecerá e é aí que precisamos nos concentrar.
pinMode(pin, OUTPUT);
A parte pinMode
relevante para esta discussão é:
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
}
(A implementação completa pode ser encontrada em fiação_digital.c )
Então, aqui, digitalPinToBitMask
parece estar usando pin
para calcular um bit intermediário. Explorando ainda mais, digitalPinToBitMask
é uma macro definida em Arduino.h
cuja definição é esta linha única:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Este forro de aparência estranha faz uma tarefa muito simples. Ele indexa o elemento P th na matriz digital_pin_to_bit_mask_PGM
e o retorna. Essa matriz digital_pin_to_bit_mask_PGM
é definida no pins_arduino.h
mapa de pinos da placa específica que está sendo usada.
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),
...
};
Essa matriz possui 20 elementos no total, então estamos sem sorte. 999 indexará um local de memória na memória flash fora dessa matriz, levando a um comportamento imprevisível. Ou será?
Ainda temos outra linha de defesa contra a anarquia de tempo de execução. É a próxima linha da função pinMode
:
uint8_t port = digitalPinToPort(pin);
digitalPinToPort
nos leva por um caminho semelhante. É definido como uma macro junto com digitalPinToBitMask
. Sua definição é:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Agora, indexamos o elemento P th , digital_pin_to_port_PGM
que é uma matriz definida no mapa de pinos:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
Essa matriz contém 20 elementos, portanto, 999 está novamente fora de alcance. Novamente, este comando lê e retorna um valor da memória flash cujo valor não podemos ter certeza. Isso levará novamente a um comportamento imprevisível a partir de agora.
Ainda existe uma última linha de defesa. Esse é o if
check-in pinMode
no valor de retorno de digitalPinToPort
:
if (port == NOT_A_PIN) return;
NOT_A_PIN
é definido como 0 pol Arduino.h
. Portanto, se o byte retornado de digitalPinToPort
for zero, pinMode
falhará e retornará silenciosamente.
De qualquer forma, pinMode
não pode nos salvar da anarquia. 999 está destinado a resultar em desgraça.
TL; DR, o código será executado e o resultado será imprevisível. Provavelmente, nenhum pino será definido OUTPUT
e digitalWrite
falhará. Se você tiver uma sorte excepcionalmente ruim, um pino aleatório pode ser definido como OUTPUT
e digitalWrite
pode ser definido como HIGH
.