Defensive programming is a style of programming that anticipates potential errors and takes steps to prevent or mitigate them. Assertions are a key tool in defensive programming, as they allow you to express and validate assumptions about your code.
Here are some ways to use assertions for defensive programming:
Example 1: Check function preconditions:
int strlen(const char* str) {
assert(str != nullptr);// ...
}
Example 2: Validate function postconditions:
int pop(std::stack<int>& s) {
assert(!s.empty());
int top = s.top();
s.pop();
assert(top == s.top());
return top;
}
Example 3: Verify loop invariants:
int sum(const std::vector<int>& v) {
int total = 0;
for (size_t i = 0; i < v.size(); ++i) {
total += v[i];
assert(total >= 0);
}
return total;
}
Example 4: Check switch cases and if-else chains:
char to_lower(char c) {
switch (c) {
case 'A': return 'a';
case 'B': return 'b';
// ...
default:
assert(false && "Invalid character");
}
}
Example 5: Test user input:
void save_preferences(int pref) {
assert(pref >= 0 && pref < 10);// ...
}
Some tips for effective defensive programming with assertions:
Remember, the goal of defensive programming is to make your code fail quickly and visibly when something goes wrong, rather than silently producing incorrect results. Assertions help you achieve this by making your assumptions explicit and verifiable.
Answers to questions are automatically generated and may not have been reviewed.
Learn how we can ensure that our application is in a valid state using compile-time and run-time assertions.