Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

C99 and C90 allow a pointer to be cast into and out of void *. As a result, it is possible to silently convert from one pointer type to another without the compiler diagnosing the problem by storing or casting a pointer to void * and then storing or casting it to the final type. In this noncompliant code example, the type checking system is circumvented due to the caveats of void pointers.

Code Block
bgColor#FFCCCC
langc
char *loop_ptr;
int *int_ptr;

int *loop_function(void *v_pointer) {
  /* ... */
  return v_pointer;
}
int_ptr = loop_function(loop_ptr);

...

Because the input parameter directly influences the return value, and loop_function() returns an int *, the formal parameter v_pointer is redeclared to only accept int *.

Code Block
bgColor#ccccff
langc
int *loop_ptr;
int *int_ptr;

int *loop_function(int *v_pointer) {
  /* ... */
  return v_pointer;
}
int_ptr = loop_function(loop_ptr);

...

Many architectures require that pointers are correctly aligned when accessing objects bigger than a byte. There are, however, many places in system code where you receive unaligned data (for example, the network stacks) that needs to be copied to a properly aligned memory location, such as in this noncompliant code example.

Code Block
bgColor#FFCCCC
langc
char *data;
struct foo_header *tmp;
struct foo_header *header;

tmp = data + offset;
memcpy(&header, tmp, sizeof(header));

if (header.len < FOO)
/* ... */

...

This compliant solution does not use the foo_header pointer.

Code Block
bgColor#ccccff
langc
char *data;
struct foo_header header;

memcpy(&header, data + offset, sizeof(header));

if (header.len < FOO)
/* ... */

...