One big source of bugs in C is out-of-bounds accesses to arrays. We can add bounds checking using the following macro:

```
/* usually put in some project wide common header file */
#define bounds(_i, _n) (assert((unsigned)(_i) < (_n)), (_i))
```

To use this, index arrays using the following idiom:

```
array[bounds(i, ARRAY_SIZE)]
```

First, the index (`i`

) is compared against the array bound (`ARRAY_SIZE`

); then the value of the index is returned. If the index is negative, then the use of the `unsigned`

causes it to be a very large number, and will also cause the bounds check to fail. If assertions are turned off (i.e. `NDEBUG`

is defined), then `bounds()`

just returns the index.

We incorporate the `bounds()`

macro into accessor macros. For instance:

```
#define x_val_int_stack(_s,_i) \
x_vals_int_stack(_s)[bounds(_i,x_len_int_stack(_s)-1)]
#define val_int_stack(_s, _i) ((void)0,x_val_int_stack(_s,_i))
```

These indexing-accessor macros should be used in place of indexing an accessor macro. Thus:

```
void
pop_int_stack(
int_stack stack
)
{
VERIFY_INT_STACK(stack);
#if( CHECKSUM_INT_STACK )
{
int len = len_int_stack(stack);
x_chksum_int_stack(stack) ^= (unsigned)len;
len--;
x_chksum_int_stack(stack) ^=
(unsigned)
```**val_int_stack(stack, len)**;
x_chksum_int_stack(stack) ^= (unsigned)len;
}
#endif
x_len_int_stack(stack)--;
VERIFY_INT_STACK(stack);
}

Of course, this is only used as an example. It doesn't do any additional error checking, since `VERIFY_INT_STACK(stack)`

would already have checked for `len`

being within bounds.

Next Prev Main Top Feedback