Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Wordsmithing

...

In particular, do not default the test for non-zero. For instance, suppose a foo() function returns 0 to indicate failure, or a non-zero value to indicate success. Testing for inequality with zero:

Code Block
bgColor#ccccff
if (foo() != 0) ...

is preferable to

Code Block
bgColor#ffcccc
if (foo()) ...

despite the convention that 0 indicates failure. Explicitly testing for inequality with zero benefits maintainability if foo() is later modified to return -1 rather than 0 on failure.

...

Code Block
bgColor#ffcccc
LinkedList bannedUsers;

int is_banned(User usr) {
  int x = 0;

  Node cur_node = (bannedUsers->head);

  while (cur_node != NULL) {
    if(strcmp((char *)cur_node->data, usr->name) {
      x++;
    }
    cur_node = cur_node->next;
  }

  return x;
}

void processRequest(User usr) {
  if(is_banned(usr) == 1) {
    return;
  }
  serveResults();
}

...

If a banned user is listed twice, the user is granted access. Although is_banned() follows the common convention of returning non-zero for true, processRequest only checks for equality with 1.

...

Because most functions only guarantee a return value of non-zero for true, the above code above is better written by checking for inequality with 0 (false) as follows.:

Code Block
bgColor#CCCCFF
LinkedList bannedUsers;

int is_banned(User usr) {
  int x = 0;

  Node cur_node = (bannedUsers->head);

  while(cur_node != NULL) {
    if (strcmp((char *)cur_node->data, usr->name) {
      x++;
    }
    cur_node = cur_node->next;
  }

  return x;
}

void processRequest(User usr) {
  if (is_banned(usr) != 0) {
    return;
  }
  serveResults();
}

Noncompliant Code Example

In this noncompliant code example, function failures Function status can typically be indicated by one of the following return values: returning -1 on failure, a non-zero numberor any nonnegative number on success. While this is a common convention in the standard C library, it is discouraged in ERR02-C. Avoid in-band error indicators.

Although failures are frequently indicated by a return value of zero, there are common conventions that may conflict in the future with code where the test for non-zero is not explicit. In this case, defaulting the test for non-zero welcomes bugs if and when a developer modifies foo() to return an error code or -1 rather than 0 to indicate a failure (all of which are also common conventions). 

Code Block
bgColor#ffcccc


int validateUser(User usr) {
  if(listContains(validUsers, usr)) {
    return 1;
  }

  return 0;
}

void processRequest(User usr, Request request) {
  if(!validateUser(usr)) {
    return "invalid user";
  }
  else {
    serveResults();
  }
}

The Although the code above will work as intended. However, it is very feasible possible that a future modification will result in the following.:

Code Block
bgColor#ffcccc
errno_t validateUser(User usr) {
  if(list_contains(allUsers, usr) == 0) {
    return 303;  // user not found error code
  }
  if(list_contains(validUsers, usr) == 0) {
    return 304; // invalid user error code
  }

  return 0;
}

void processRequest(User usr, Request request) {
  if(!validateUser(usr)) {
    return "invalid user";
  }

  serveResults();
}

...

The code above works correctly. However, in order to simplify the login code or to facilitate checking a user's password more than once, a programmer might separate the password checking code from the login function. they might do so in the following way.

...