It is impossible to implement f() to deliver either the weak or strong exception safety guarantees if the behaviour of the functions it calls isn't known. This is particularly relevant when the user of f() supplies the functions to be called as callbacks, implementations of virtual member functions, or via template parameters.
If we assume an object-oriented design with fully encapsulated data then each function need only be held directly responsible for aspects of the object of which it is a member. For the rest it must rely on the functions it calls to behave correctly in respect of the objects with which it interacts.