not incur runtime overhead in production and guard against programming error
I'm a huge fan of assertions and use them to document 'programmer screwed up' and to get notified of cases when that happens; I find that a more corect description then 'guarding against'. However we leave assertions on in release builds as well: tracking down cases of UB only happening in release builds (most often due to someone forgetting to initialize something) is hard enough already, and we found that leaving assertions on can help with that. Only in certain hot paths which prove the runtime overhead matters (and there's really not a lot of those) we'll turn them off.
I'm a huge fan of assertions and use them to document 'programmer screwed up' and to get notified of cases when that happens; I find that a more corect description then 'guarding against'. However we leave assertions on in release builds as well: tracking down cases of UB only happening in release builds (most often due to someone forgetting to initialize something) is hard enough already, and we found that leaving assertions on can help with that. Only in certain hot paths which prove the runtime overhead matters (and there's really not a lot of those) we'll turn them off.