Sort of..an individual smart contract is completely immutable; the code cannot be updated. You can create a proxy smart contract that points to the contracts actually handling execution, and update those pointers to point to new, updated version of the code which is what I assume you're referring to.
Plenty of popular smart contracts do not do this though, and are fully immutable. Rather than updates, the developers upload a new version. Users can use the new version, or stay on the old one forever (the developers cannot delete it).
Regardless of which one, though, this is known ahead of time. A user (or, more likely, a community of users) can inspect the code and see to what extent the key holders can modify functionality.
Plenty of popular smart contracts do not do this though, and are fully immutable. Rather than updates, the developers upload a new version. Users can use the new version, or stay on the old one forever (the developers cannot delete it).
Regardless of which one, though, this is known ahead of time. A user (or, more likely, a community of users) can inspect the code and see to what extent the key holders can modify functionality.