In procedural languages where functions are a key player, the design by contract paradigm basically says that there is an agreement between a function that takes parameters and the caller.
The agreement goes something like "if the caller ensures that the preconditions of the function are met, then the function will behave in an expected manner and/or return expected values."
If we write code strictly in this way, then the caller alone is responsible for ensuring proper inputs to functions. But in the name of defensive programming, it seems wise to include internal safeguards in case the caller does something stupid.
When it come to software architecture and design, what is the best approach here?