Using your original wording...
Wait, what? segfaulting is ok,
Yes! It's called Contract Programming. Which can be summarised as saying:
"If you give me what I've asked for, I will guarentee to give you back what you need. But if you do not, I will fail as early and as hard as possible".
Quoting the relevant part of the linked article:
When using contracts, a supplier should not try to verify that the contract conditions are satisfied; the general idea is that code should "fail hard", with contract verification being the safety net. DbC's "fail hard" property simplifies the debugging of contract behavior as the intended behaviour of each routine is clearly specified. This distinguishes it markedly from a related practice known as defensive programming, where the supplier is responsible for figuring out what to do when a precondition is broken. More often than not, the supplier throws an exception to inform the client that the precondition has been broken, and in both cases - DbC and defensive programming - the client must figure out how to respond to that. DbC makes the supplier's job easier.
The purpose is that instead of every routine having to validate its inputs, which inevitably means that the same, often expensive checks, are performed over and over, at every level of the code. Each higher level is responsible for checking that what it passes to lower levels is correct. That way, checks need only be performed at those levels where data can come from unreliable sources. ie. externally.
Take, for example, a class definition. Many class generator modules allow the automatic generation of setters. And as part and parcel of that, many will generate code to validate the values being set.
But, it is a (fairly) widely upheld principle of OO design, that setters and getters should not be a part of the published interface. This because it causes close coupling between the internal, logical, data design and the calling code. Classes should only export methods that perform services that manipulate the encapsulate state, not give access to that state. Otherwise they are simply wrappers over structs.
Now, if a module does not export its setters, then they can only be called internally. And only with data that is derived from the arguments to the published interface.And once the algorithms for the methods have been thoroughly tested--through functional verification--, if the contracts of the published interface are adhered to by callers, then any values that will be passed to the setters internally, are by definition, correct. So there is no purpose in validating them again at run time. Which means any such validation code in the setter routines is just a pure waste of cycles.
Of course, during the development and testing cycle, it can be useful to have assertions embedded within the setters, that fail hard if the programmer inadvertantly breaks the contract. But once the code has been functionally verified, those assertions can be disabled for efficiency.
Not only does this method of progamming avoid the duplication of data validation. It also avoids the need for all the checks on data returned. It simplifies the code at all levels, and improves runtime performance as a side benefit, with no compromise on reliability. And those simplifications and performance improvements are compounded every time the DbC code is re-used.
It's not just win+win; it's (win+win)^reuses.
Compare favourably with the food industry. We do not expect every consumer to have a full-blown biochemical laboratory in their homes and test every purchase they make. The raw ingredients, (external data), are sampled at input (external input validation). The recipe is tested thoroughly (functional verification). And samples of each batch are tested as they are produced (integration testing).
If other industries followed the prevelent software practice of testing and re-testing everything at every stage, they would grind to a stand-still. Just as the software industry is doing now.
Belt & braces isn't good practice. It just demonstrates a total lack of confidence. And paranoia.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.