C++ issues

There are some additional techiniques that you can use in C++ programs.

CheckedPtr template

The <rcheck/malloc.h> header file defines a
CheckedPtr template that you can use in place of a raw pointer in C++ programs.
In order to use this template, you must link your program with librcheck.

This template acts as a smart pointer; its initializers
obtain complete information about the heap buffer on an assignment operation
and initialize the current pointer position. Any attempt to dereference the
pointer causes bounds-checking to be performed and prints a diagnostic error
in response an attempt to dereference a value beyond the bounds of the buffer.

You can modify this template to suit
the needs of the program. The bounds-checking performed by the checked pointer
is restricted to checking the actual bounds of the heap buffer, rather than
the program's requested size.

Clean C

For C programs it's possible to compile individual modules that obey certain
rules with the C++ compiler to get the behavior of the CheckedPtr
template. C modules obeying these rules are written to a dialect of
ANSI C referred to as Clean C.

The Clean C dialect is the subset of ANSI C that's compatible with the C++
language. Writing Clean C requires imposing coding conventions to the C code
that restrict use to features that are acceptable to a C++ compiler. This section
provides a summary of some of the more pertinent points to be considered. It
is a mostly complete but by no means exhaustive list of the rules that must
be applied.

To use the C++ checked pointers, the module, including all header files it includes,
must be compatible with the Clean C subset.
All the system header files for QNX Neutrino satisfy this requirement.

The most obvious aspect to Clean C is that it must be strict ANSI C with respect
to function prototypes and declarations. The use of K&R prototypes or definitions
isn't allowed in Clean C.
Similarly, you can't use default types for variable and function declarations.

Another important consideration for declarations is that you must provide
forward declarations when referencing an incomplete structure or union.
This frequently
occurs for linked data structures such as trees or lists.
In this case, the forward
declaration must occur before any declaration of a pointer to the object in
the same or another structure or union.
For example, you could declare a list node as follows:

Operations on void pointers are more restrictive in C++. In particular, implicit
coercions from void pointers to other types aren't allowed, including both
integer types and other pointer types. You must explicitly cast void pointers to other types.

The use of const should be consistent with C++ usage. In particular, pointers
that are declared as const must always be used in a compatible fashion.
You can't pass const pointers as non-const
arguments to functions unless you typecast the const away.

C++ example

Here's how you could use checked pointers in the overrun example given
earlier to determine the exact source of the error: