Не программист для UB, а UB для программиста. хех. Языки делаются, чтобы что-то работало, а не чтобы реализовать абстрактные концепции. Линус прав: если для работы с железом что-то нужно, но стандарт языка говорит что это - UB, то стандарт идёт лесом.
Впрочем, можно просто определить области отображаемых на память регистров как всегда аллоцированные объекты. В результате компилятор обязан будет генерировать чтение по адресу, так как на некоторых платформах это будет не UB.
Ну а всегда аллоцированный объект, очевидно, нельзя передать в функцию free. Семантика простая - чтение по адресу памяти (как определено в memory model)
Если стандарт не натягивается на глобус, то дополняем стандарт, а не выкидываем глобус. Считаем, что есть неявные идентификаторы (зависимые от платформы).