Skip to content

Commit

Permalink
[docs] Moved the cage consting guide into the cage cleaners guide. Re…
Browse files Browse the repository at this point in the history
…moved

the comment that a good description of consting should be added, as this is
it :-)


git-svn-id: https://svn.parrot.org/parrot/trunk@17554 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
paultcochrane committed Mar 17, 2007
1 parent abe6c5f commit d9148bc
Showing 1 changed file with 113 additions and 4 deletions.
117 changes: 113 additions & 4 deletions docs/project/cage_cleaners_guide.pod
Expand Up @@ -60,12 +60,121 @@ do lots of checking that wouldn't normally be possible. Walk the
source code adding the C<const> qualifier wherever possible. The
biggest bang is always in passing pointers into functions.

=item * C<const> explaining
=head2 Why consting is good

The description above is pretty sparse. A good description of
C<const> and its benefit would be helpful for newcomers.
In Perl, we have the C<use constant> pragma to define unchanging
values. The L<Readonly> module extends this to allow arrays and
hashes to be non-modifiable as well.

=back
In C, we have C<const> numbers and pointers, and using them wherever
possible lets us put safety checks in our code, and the compiler
will watch over our shoulders.

=head3 C<const> numbers

The easiest way to use the C<const> qualifier is by flagging numbers
that are set at the top of a block. For example:

int max_elements;

max_elements = nusers * ELEMENTS_PER_USER;

...

array[max_elements++] = n;
/* but you really meant array[max_elements] = n++; */

Adding a C<const> qualifier means you can't accidentally modify
C<max_elements>.

const int max_elements = nusers * ELEMENTS_PER_USER;

=head3 C<const> pointers

If a pointer is qualified as const, then its contents cannot be
modified. This lets the compiler protect you from doing naughty
things to yourself.

Here are two examples for functions you're familiar with:

int strlen( const char *str );
void memset( char *ptr, char value, int length );

In the case of C<strlen>, the caller is guaranteed that any string
passed in won't be modified. How terrible it would be if it was
possible for C<strlen> to modify what gets passed in!

The const on C<strlen>'s parameter also lets the compiler know that
C<strlen> can't be initializing what's passed in. For example:

char buffer[ MAX_LEN ];

int n = strlen( buffer );

The compiler knows that C<buffer> hasn't been initialized, and
that C<strlen> can't be initializing it, so the call to C<strlen>
is on an uninitialized value.

Without the const, the compiler assumes that the contents of any
pointer are getting initialized or modified.

=head3 C<const> arrays

Consting arrays makes all the values in the array non-modifiable.

const int days_per_month[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

You don't want to be able to do C<days_per_month[1] = 4;>, right?
(We'll ignore that about 25% of the time you want C<days_per_month[1]>
to be 29.)

=head3 Mixing C<consts>

Combining C<const>s on a pointer and its contents can get confusing.
It's important to know on which side of the asterisk that the
C<const> lies.

To the left of the asterisk, the characters are constant. To the
right of the asterisk, the pointer is constant.

Note the difference between a pointer to constant characters:

/* Pointer to constant characters */
const char *str = "Don't change me.";
str++; /* legal, now points at "o" */
*str = "x"; /* not legal */

and a constant pointer to characters:

/* Constant pointer to characters */
char * const str = buffer;
str++; /* not legal */
*str = 'x'; /* buffer[0] is now 'x' */

Note the difference between which side of the asterisk that the
C<const> is on.

You can also combine the two, with a constant pointer to constant
characters:

const char * const str = "Don't change me";

or even an array of constant pointers to constant characters:

const char * const days[] =
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

If you see a declaration you don't understand, use C<cdecl>. It's
standard in many C compiler suites, and is freely available around
the net.

$ cdecl
Type `help' or `?' for help
cdecl> explain const char * str;
declare str as pointer to const char
cdecl> explain char * const str;
declare str as const pointer to char=back

=head2 Decreasing the amount of repeated code

Expand Down

0 comments on commit d9148bc

Please sign in to comment.