Я считаю, что этот код должен был быть неверно сформирован на основе [stmt.dcl] / 3 :
Возможно передать в блок, но не вспособ обойти объявления с инициализацией (в том числе в условиях и инструкциях init). Программа, которая переходит от точки, в которой переменная с автоматическим хранением находится вне области действия, к точке, в которой она находится в области видимости, является некорректно сформированной , если переменная не имеет бессодержательной инициализации ([dcl.init]).
Ударная шахта.Ваша переменная mask
не имеет незаполненной инициализации .По крайней мере, насколько я понимаю, «плохо сформированный» неявно требует диагностики, то есть компилятор, соответствующий стандартам, должен выдавать сообщение об ошибке.Так что никакого неопределенного поведения, это просто не должно было бы скомпилироваться.
Таким образом, я бы сказал, что отсутствие диагностики здесь определенно следует рассматривать как ошибку компилятора.Обратите внимание, однако, что ни одна из версий GCC, которую можно примерить на Godbolt, не принимает этот код (и они уходят довольно далеко назад).Казалось бы, в Arduino IDE должна использоваться безнадежно устаревшая / неработающая версия GCC, если она действительно скомпилировала этот код без колебаний ...
пример правильных компиляторов, жалующихся на этот
Чтобы устранить проблему, просто оберните вашу переменную в область видимости блока так, чтобы не было никакого возможного потока управления, который мог бы войти в область, в которой переменная объявлена, без передачи ее объявления, как вы уже обнаружили сами.Например, превратить это
void f(int x)
{
switch (x)
{
case 1:
const int y = 42; // error
break;
case 2:
break;
}
}
в
void f(int x)
{
switch (x)
{
case 1:
{
const int y = 42; // OK
break;
}
case 2:
break;
}
}