Blog Archive

Tuesday, July 9, 2019

Defensive programming

source:
https://akrzemi1.wordpress.com/2015/01/12/defensive-programming/

Have you ever asked yourself, or participated in a discussion on whether “defensive programming”is a good or a bad thing? The issue is controversial, and recently, while watching talk “Defensive Programming Done Right, Part I” by John Lakos, I realized (I think) why. Term “undefined behavior” means different things to different people.
Rather than saying something myself, let me ask you a question. Given the following initial code:
1
2
3
4
5
6
7
bool is_monitored(const Monitor* m, const TaskId* t)
{
  auto it = std::find(m->monitored_tasks().begin(),
                      m->monitored_tasks().end(),
                      *t);
  return it != m->monitored_tasks().end();
}
Assuming that we never expect m or t to be null, which of the following variants would you call a “defensive programming” technique?
Variant A:
1
2
3
4
5
6
7
8
9
10
bool is_monitored(const Monitor* m, const TaskId* t)
{
  if (m == nullptr) return false;
  if (t == nullptr) return false;
 
  auto it = std::find(m->monitored_tasks().begin(),
                      m->monitored_tasks().end(),
                      *t);
  return it != m->monitored_tasks().end();
}
Variant B:
1
2
3
4
5
6
7
8
9
10
bool is_monitored(const Monitor* m, const TaskId* t)
{
  if (m == nullptr) throw std::logic_error("...");
  if (t == nullptr) throw std::logic_error("...");
 
  auto it = std::find(m->monitored_tasks().begin(),
                      m->monitored_tasks().end(),
                      *t);
  return it != m->monitored_tasks().end();
}
Variant C:
1
2
3
4
5
6
7
8
9
10
bool is_monitored(const Monitor* m, const TaskId* t)
{
  assert (m);
  assert (t);
 
  auto it = std::find(m->monitored_tasks().begin(),
                      m->monitored_tasks().end(),
                      *t);
  return it != m->monitored_tasks().end();
}
Variant D:
1
2
3
4
5
6
7
8
9
10
bool is_monitored(const Monitor* m, const TaskId* t)
{
  if (m == nullptr) log_error("..."); // and continue
  if (t == nullptr) log_error("..."); // and continue
 
  auto it = std::find(m->monitored_tasks().begin(),
                      m->monitored_tasks().end(),
                      *t);
  return it != m->monitored_tasks().end();
}
Whatever your answer is, note that other developer’s choice may be different. If you are in disagreement with your colleague whether “defensive programming” is a good or an evil thing, it is possible that you both entirely agree on what is good and what is evil, and the only difference is in how you define “defensive programming”.
I do not intend to give my choice here. My only goal with this short post is to note that the term is ambiguous.

No comments:

Post a Comment