TPP Topic 25: Assertive Programming

See the first post in The Pragmatic Programmer 20th Anniversary Edition series for an introduction.

Exercise 16

A quick reality check. Which of these “impossible” things can happen?

  1. A month with fewer than 28 days
  2. Error code from a system call: can’t access the current directory
  3. In C++: a = 2; b = 3; but (a + b) does not equal 5
  4. A triangle with an interior angle sum ≠ 180°
  5. A minute that doesn’t have 60 seconds
  6. (a + 1) <= a

All of them!

  1. In 1752, Great Britain changed from using the Julian calendar to the Gregorian calendar. This required a correction of 11 days; causing September to have only 19 days.
  2. There are no certainties when it comes to file systems (take a look at Dan Luu’s excellent talk Files are fraught with peril). To name but a few reasons for this particular error: the directory could have been deleted by another process, the process making the system call may not have permissions to access the directory or the drive where the directory is located could have been disconnected.
  3. Without extra care, concurrency could cause a to be updated before (a + b) is executed.
  4. In curved geometries the interior angles of a triangle do not sum to 180°. In elliptic geometry the sum will be greater than 180° and in hyperbolic the sum will be less than 180°.
  5. Dates and times are also fraught with peril! In this case, leap seconds can cause minutes with 59 or 61 seconds.
    • Note: at the time of writing, all leap seconds have been positive - causing a minute to have 61 seconds. A negative leap second would occur if the earth’s rotation were to increase in speed instead of decrease as it has been.
  6. Integer overflow could cause the value of a + b to be negative. The exact scenarios under which overflow can occur depend on the language and the compiler/interpreter being used; the Integer overflow page on Rosetta Code has examples from many different languages. For this specific case I present an example using Go (GitHub):
// overflow.go

package main

import "fmt"

func main() {
	var a int32 = 2147483647
	fmt.Printf("a = %d\n", a)
	fmt.Printf("(a + 1) <= a = false, got %t\n", (a+1) <= a)
	fmt.Printf("(%d + 1) = 21474836478, got %d\n", a, a+1)
}

Output:

$ go run overflow.go
a = 2147483647
(a + 1) <= false, got true
(2147483647 + 1) = 21474836478, got -2147483648

Program exited.
comments powered by Disqus