компилятор упорно не хочет вычислять выражение &((int*)f)[3] при компилировании
Что говорит?
имя функции - это константа на момент компиляции
Ложное утверждение. Адрес функции становится известен только на этапе линковки, а если функция импортирована из dll -- то только в момент загрузки. Если линковка релоцируемая, то адрес может измениться в момент загрузки. Другое дело, что константная строка в этом смысле мало отличается от функции.
Сложная конструкция должна выглядеть вот так:
void (*fptr)(int) = (void(*)(int)) (((int*)f) + 3);
Вариант с (f+3) компилироваться не будет, т.к. арифметика указателей не работает с указателями на функции.
В линуксе эта конструкция компилируется и работает.