Я тоже так умею: "а думать перед написанием кто будет?" Ведь тройка у тебя "приводится" к
указателю, а не к
смещению.
Т.е. написано
(* (void(*)()) 3 )(); /* это функция, размещённая по адресу 3 */
А не
(* ( (void(*)()) 0) + 3) )(); /* это - третий вектор в таблице, размещённой по адресу 0 */
Не правда ли?
Напиши
*(__flash int*)3 = 0;
и
* ((__flash int*)0 + 3) = 0;
и сравни результат.
И то, что IAR пошёл на поводу у атмела и алгоритм вычислений для * ((type*)const) в зависимоcти от типа разный - это несколько странно.