Software Quality and Defensive Programming

Choose a study mode

Play Quiz
Study Flashcards
Spaced Repetition
Chat to Lesson

Podcast

Play an AI-generated podcast conversation about this lesson
Download our mobile app to listen on the go
Get App

Questions and Answers

In the context of software quality, what is the primary goal of defensive programming?

  • To detect and handle run-time errors. (correct)
  • To speed up the development process.
  • To eliminate all bugs from the code.
  • To reduce the amount of testing required.

Which of the following is NOT a characteristic of robust software?

  • Stable behavior even in the presence of errors.
  • Predictable behavior.
  • Correct behavior.
  • Unstable behavior in the presence of errors. (correct)

What is the potential consequence of not having a well-thought-out error handling strategy?

  • Faster execution of code.
  • Inconsistent code quality in error checking across system. (correct)
  • Reduced development time.
  • Improved code readability.

When should you handle an error according to the principle of local error handling?

<p>Handle the error in the same place where it was detected. (C)</p> Signup and view all the answers

In which scenario is it most appropriate to reflect error status up to the caller?

<p>When using utility packages that may not know how to handle errors in a way acceptable to a higher-level application. (D)</p> Signup and view all the answers

Which of the following is a primary reason for using assertions in code?

<p>To check for conditions that should always be true, primarily during development. (D)</p> Signup and view all the answers

Why should assertions generally be avoided for input validation in a UI?

<p>Assertions can lead to abrupt program termination, which is not user-friendly. (B)</p> Signup and view all the answers

In C, if a function that returns a pointer needs to signal an error, what is the common practice?

<p>Return NULL. (C)</p> Signup and view all the answers

What is a 'partial function' in the context of programming?

<p>A function that may not return a value for all possible input values. (A)</p> Signup and view all the answers

Which of the following is a good practice in defensive programming?

<p>Check for cases that “can't occur” just in case. (B)</p> Signup and view all the answers

In C, how do functions typically handle errors when they cannot return a specific 'invalid' value?

<p>By returning an error code and passing the 'return' value by reference. (D)</p> Signup and view all the answers

Why is it important for assertions not to have side effects?

<p>Because assertions might be disabled in production, and their side effects would then be lost. (C)</p> Signup and view all the answers

What is one potential downside of checking for every conceivable error condition in defensive programming?

<p>It can significantly increase the amount of code and testing required. (C)</p> Signup and view all the answers

Which of the following best describes the use of assert in defensive programming?

<p>Mostly for debugging and verifying conditions that should never occur. (D)</p> Signup and view all the answers

If a function, designed to calculate the square root, receives a negative number, how would a language that supports IEEE float/double numbers typically handle this situation?

<p>Return a NaN (Not a Number) value. (D)</p> Signup and view all the answers

What is a key difference between how errors should be handled in the testing/debugging phase versus the production phase?

<p>In testing, it's acceptable to abort with a message, while in production, the system should attempt to recover gracefully. (C)</p> Signup and view all the answers

Why is it important to verify external inputs in defensive programming?

<p>To ensure the program doesn't crash due to unexpected or invalid data. (A)</p> Signup and view all the answers

What does “Robustness” mean in the context of software quality factors?

<p>The ability of a software to maintain correct, predictable, and stable behavior even when errors occur. (A)</p> Signup and view all the answers

What's a key reason for handling errors locally where they're detected, instead of sending them elsewhere?

<p>It keeps the complex error-handling code contained and localized, rather than smeared throughout the system. (C)</p> Signup and view all the answers

In defensive programming, what kinds of values should you check for?

<p>Extreme values such as large positive numbers, negative numbers, and zero. (C)</p> Signup and view all the answers

What is the significance of 'pre- and post-conditions' in defensive programming?

<p>They are conditions that should be true before and after a critical piece of code executes, ensuring it behaved as expected. (C)</p> Signup and view all the answers

In the context of handling errors in C, what does it mean to 'return an error code and pass the “return” value by reference'?

<p>The function returns an error code while also using a pointer to store the actual result. (D)</p> Signup and view all the answers

Why should assertions not be used for handling user input errors in a UI?

<p>Assertions stop the program, leading to a poor user experience. (B)</p> Signup and view all the answers

If a function that returns a pointer encounters an error in C, what should it typically return?

<p><code>NULL</code> (D)</p> Signup and view all the answers

How do modern programming languages typically support assertions?

<p>By checking a condition at runtime and exiting with an error message if it’s false. (A)</p> Signup and view all the answers

If the programming language provides exception handling, when should it be used?

<p>For signaling errors; throws an exception otherwise (C)</p> Signup and view all the answers

What is the recommended action when a "fatal" error is detected?

<p>Abort the program and inform the user, if possible. (D)</p> Signup and view all the answers

When is it appropriate to use assertions to validate conditions?

<p>To verify preconditions in functions during development. (A)</p> Signup and view all the answers

In languages like Java, Python, and JavaScript, which offer exception handling, what typically happens when a function encounters an issue?

<p>The function throws an exception. (B)</p> Signup and view all the answers

Which of the following constitutes a risky practice that should be avoided when using assertions?

<p>Relying on them to handle potential external errors in a production environment. (C)</p> Signup and view all the answers

What kind of programming is like Defensive Driving?

<p>Defensive programming. (A)</p> Signup and view all the answers

What does defensive programming uncover?

<p>Run-time conditions that prevent your software from operating correctly. (D)</p> Signup and view all the answers

What should you, according to the slides, NOT leave up to the individual coder's judgement?

<p>Error Handling (C)</p> Signup and view all the answers

The slides mention that if code is not tested, it can turn into a:

<p>Fragile system. (B)</p> Signup and view all the answers

The slides mention 'Errors are not all the same' and that they have different characteristics. What are these characteristics known as?

<p>Kinds of Errors (A)</p> Signup and view all the answers

The slides mention 'errors are not all the same' and that they have different severities, what are the two?

<p>Fatal and Nonfatal (B)</p> Signup and view all the answers

What two functions are mentioned to return the number of arguments scanned/printed successfully??

<p>printf and scanf (A)</p> Signup and view all the answers

According to the slides, how can you typically turns assertions off at compile time?

<p>#define NDEBUG (D)</p> Signup and view all the answers

The slides mentioned a USS ship of the line that had issues with a divide by zero error, what ship was it?

<p>USS Yorktown (C)</p> Signup and view all the answers

According to the slides, what is a rare condition?

<p>Module B returns that module A called it with bad args (D)</p> Signup and view all the answers

Flashcards

Robustness

Correct, predictable, and stable behavior even in the presence of errors, expected from commercial software.

Defensive programming

Writing code to detect and handle run-time errors, ensuring software stability and reliability.

Testing

Ensuring that code is free of defects by systematically checking and validating its behavior.

Debugging

Fixing defects uncovered by testing, crucial for improving software quality and reliability.

Signup and view all the flashcards

Fixable code errors

Errors in your code that require fixing to ensure proper functionality and stability.

Signup and view all the flashcards

Run-time errors

Errors that occur during program execution, requiring robust handling to prevent crashes.

Signup and view all the flashcards

Software Robustness

The ability of software to maintain correct behavior despite errors, ensuring stable operation.

Signup and view all the flashcards

External data errors

Problems with external data or conditions outside of your control, that require detection and handling.

Signup and view all the flashcards

Erroneous internal usage

Internal errors in your own software that can lead to crashes or unexpected behavior.

Signup and view all the flashcards

Rare Conditions

Uncommon situations or unexpected results that can cause issues, like network connection drops.

Signup and view all the flashcards

"Fatal" Errors

Severe errors that prevent the program from continuing execution, requiring termination.

Signup and view all the flashcards

"Nonfatal" Errors

Errors where recovery is possible, allowing the program to continue running.

Signup and view all the flashcards

Local error handling

Handling errors within the same context they were detected, promoting modularity and easier debugging.

Signup and view all the flashcards

Reflecting errors upward

Passing error status back up to the calling function, allowing higher-level logic to manage the error appropriately.

Signup and view all the flashcards

Pointer Error Signals in C

Functions that return a pointer must signal errors, often using NULL to indicate failure.

Signup and view all the flashcards

Exception Handling

A function returns a value if things go well, or throws an exception otherwise.

Signup and view all the flashcards

Nullable types

Variable that can represent either a value or the absence of a value.

Signup and view all the flashcards

Defensive programming

Self-testing code to expose bugs early.

Signup and view all the flashcards

Assertion

A checkable condition that causes a failure if false.

Signup and view all the flashcards

Boundary Values

Verifying extreme inputs but may require extra checks.

Signup and view all the flashcards

Check return values

Checking status after library calls and other things.

Signup and view all the flashcards

Impossible values

Returning an 'impossible' value to indicate issues.

Signup and view all the flashcards

Partial function

A function that doesn't return a result for all possible input values.

Signup and view all the flashcards

Study Notes

Software Quality and Defensive Programming

  • Software quality is enhanced through defensive programming, testing, and debugging.
  • Defensive programming involves preventing problems
  • Testing determines if code is working correctly
  • Debugging fixes defects found in testing.

Purpose of Defensive Programming

  • Primary goal to detect problems early in the development cycle.
  • An error handling strategy is a must
  • Error handling strategy ensures a consistent approach to error management throughout the system.
  • It is crucial to decide how to handle runtime errors uncovered by defensive programming.
  • Must balance comprehensive error checking with practical considerations.

Software Quality Factors: Robustness

  • Robustness is the ability to maintain correct, predictable, and stable behavior even when errors occur.
  • Errors can occur in commercial and open-source software.
  • Defensive programming writes code to detect and manage runtime errors.
  • Testing to find defects in source code
  • Debugging, the fixing of those defects

Defensive Programming Principles

  • It is similar to defensive driving where "unexpected" problems emerge
  • Anticipate potential errors in various areas:
    • Input data
    • Function arguments
    • File contents
    • Human input
    • Module behavior

Error Analysis

  • Treatment depends on the phase of software development and also factors such as "kinds" and "severities" of errors.
  • Different errors have varying characteristics and severities, impacting the possibility of continuing execution.
  • It matters if the program is in debugging or production.

Error Types

  • There are three types of errors:
    • External errors which are outside of the control of your program
    • Internal, regarding software usage
    • Rare conditions which could be your software's fault
  • Fatal Errors:
    • These prevent a program from continuing execution and are often due to issues.
    • Issues can include out-of-memory errors, null pointers, nonsensical variable values etc
    • Best to abort and provide information for diagnosis.
  • Nonfatal Errors:
    • Examples, failure to open a file or invalid phone number format.
    • During testing/debugging, notify programmers before aborting.
    • In production, maintain running and recover gracefully.

Error Handling: Local vs. Upward Reflection

  • Handle errors in the context where they are detected
  • Handle as close as possible to the point of detection.
  • Benefits include preventing invalid states from propagating and improving code documentation.
  • Some errors may need to be reflected upward, especially in utility packages.
  • Errors of this type may not be handled acceptably at a higher level.
  • Caller must implement "handle error in context."

Tools for Error Reporting

  • Printing allows for recovery/continuation
  • Tools include conditional reporting with print & abort or continue quietly.
  • Utilize assert(expression) for debugging.
  • Asserts are less useful in production code.

Defensive Programming Checks

  • Verify cases and extreme values just in case.
  • Example
if ( grade < 0 || grade > 100 ) /* impossible grades! */
 letter = '?';
else if ( grade >= 80 )
 letter = 'A';
else...
  • Internal Checks:
    • Check for potential problems like NULL pointers, out-of-range subscripts, default switch cases, and division by zero.
    • Always attempt to return an error and use asserts during development, while removing them in production.

Pre- and Post-Conditions

  • Ensure necessary conditions hold before and after critical code sections.
  • Consider potential recovery strategies.
  • The USS Yorktown incident demonstrates the importance of preventing divide-by-zero errors.
  • Verify preconditions to prevent dangerous operations.

Error Return Checks

  • Verify error returns
  • Check values from library functions and system calls.
  • Monitor output errors and failures, with input failures
  • Review scanf and printf for number of scanned/printed arguments.
  • Bad status should print error number

Error Handling in C

  • C functions signal errors, particularly through pointer returns.
  • NULL indicates an issue, while non-pointer returns rely on "invalid" values like NaN.
  • A function may return an error code, using the return value by reference, or return a pointer to the new value, using NULL to signal an error

Error Handling in Other Languages

  • Languages like Java, Python, and JavaScript use exception handling.
  • Exception handling provides a function returns a value if things go well, throws an exception otherwise
  • Nullable types, are used for handling errors
  • C lacks nullable types, unlike Java and other languages.

Defensive Programming and Testing

  • It serves as a form of self-testing code during development and production, complemented by later testing phases.

Assertions: Usage

  • Assertions are supported in modern programming languages
  • They permit checking conditions, continuing if true, and exiting with an error message if false.
  • Expression equaling zero indicates falsehood.
  • Fails the assertion and results in a message on stdout and a call to abort()
  • Assertions should handle improbable conditions from bugs with the intention to abort and verify preconditions.
  • Don't use for user input data
  • Assertions abort program on error.

Assertions: Control

  • Assertions are turned on by default and include helpful printouts.
  • They can be turned off at compile time using #define NDEBUG or -DNDEBUG in the makefile.
  • Usage depends on application-wide error handling policy.
  • Assertions should not have side effects.

Understanding Code Failure

  • Code can fail if implicit preconditions, are not checked.
  • An example includes calculating the average.
  • Code fails when using no arguments, resulting in NaN.

Assertions in Practice

  • Include <assert.h> and use assert(n > 0) in the average function to check for valid input.
  • Verify precondition of avg() - catches bug in main for cases where main should check for 0 args
  • Main reason, catch it during development phase
  • Turning of assertions during production

Assertions: Misuse

  • Do not check the number of arguments with assert() in main().
  • It's bad because input with 0 arguments is external
  • Assertions alone aren't a Substitute for input validation code
  • Should easily recover bad input

Assertions: Good vs Bad

// GOOD
int *arr;
arr = malloc(20*sizeof(int));
assert( arr != NULL ); // states what condition should be true
assert( arr ); // same meaning, NULL ptr. compares equal to 0 (false)

// BAD
int *arr;
assert( arr = malloc(20*sizeof(int)) ); // saved a line of code!
// But if assertions are disabled (-DNDEBUG), this malloc will disappear!

Partial Functions

  • In math, some inputs may have no possible output
  • On the other hand, Colloquially, a partial function maps some (but not all!) of the possibles inputs from the domain (input set) X to some element in the codomain (set containing outputs) Y
  • A partial function is a function whose output is undefined for some inputs, like sqrt(), log(), log10().
  • When programming, partial functions are a problem if their algebraic equivalent is undefined.
  • This is because they can crash, crash politely (abort) or return an “impossible” value
  • A function that for some inputs returns a value and for others terminates your program is hard to reason about / debug
  • Dying too early may not inform the end user of cause.
  • Want it to return something rather than nothing, even with negative numbers, for example.

Partial Functions: IEEE

  • It specifies the way that sqrt() should be called.
  • It always returns a return value, if x >= 0, or NaN if x<0

Assertions and Partial Functions

  • Careless use can make partial use functions
  • Always signal an error, but dont assume the function will
  • Remember there are a few occasions assert() must be used.
  • Assertions help you avoid logic errors like you avoided them.

Conclusion

  • Verification:
  • Always verify input
  • Error Handling:
  • Always try to return an error and abort.
  • User Interface:
  • Let UI communicate all errors
  • Assumptions:
  • Always assume all function arguments are always valid.

Studying That Suits You

Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

Quiz Team

Related Documents

More Like This

Use Quizgecko on...
Browser
Browser