Thank you for your reply.
I checked with VisualStudio putting a breakpoint as you suggested, and these are my results.
I'm browsing the store with a new user that has a default address in the UK, and shipping and billing addresses also in the UK, but has never been through checkout. By the way, I changed the setting as you suggested for the base address for VAT calculation, now my store is using the shipping address (I will check with an accountant as soon as I can).
The problem seems to be at line 166 of TaxManager.cs:
if (customer == null || customer.ShippingAddress == null)
because this is evaluated as true!
The customer object isn't null, but the shipping address is null even if I entered a shipping address in the admin area before logging in.
Stepping into the method, I went through line 282 of Customer.cs
_shippingAddressCache = CustomerManager.GetAddressById(this.ShippingAddressId);
where "this" represents the current user (I checked the properties and they have, almost, the correct values). The problem here is that the property ShippingAddressId is 0. If I browse through all the properties of the object, I can see that ShippingAddress is null, but ShippingAddresses contains the right address.
If I select an article and I go through the checkout process leaving the breakpoints in place, after I select the shipping address at some point I see that the property ShippingAddressId is populated with the right value, and in the following page I see that the tax is not applied (this is the expected behavior).
What I don't understand is why you are experiencing with a different situation even if the settings are the same. Am I forgetting something? You surely know the system better than me, so if you think that something can be different feel free to tell me!
In the meantime, I would like to thank you again for your help.