196 lines
7.8 KiB
Plaintext
196 lines
7.8 KiB
Plaintext
@node Coding Standards
|
|
@appendix Coding Standards
|
|
|
|
All of you should be familiar with good coding standards by now.
|
|
This project will be much easier to complete and grade if you maintain a consistent code style and employ sensible variable naming policies.
|
|
Code style makes up a significant part of your final grade for this work, and will be scrutinised carefully.
|
|
|
|
We want to stress that aside from the fact that we are explicitly basing part of your grade on this,
|
|
good coding practices will also improve the quality of your code.
|
|
This makes it easier for your team-mates to interact with it and, ultimately, will improve your chances of having a good working program.
|
|
|
|
The rest of this appendix will discuss the coding standards used in the existing PintOS codebase and how we expect you to interact with this.
|
|
|
|
@menu
|
|
* Coding Style::
|
|
* C99::
|
|
* Unsafe String Functions::
|
|
@end menu
|
|
|
|
@comment ----------------------------------------------------------------------
|
|
|
|
@node Coding Style
|
|
@section Style
|
|
|
|
Style, for the purposes of our grading, refers to how readable your
|
|
code is. At minimum, this means that your code is well formatted, your
|
|
variable names are descriptive and your functions are decomposed and
|
|
well commented. Any other factors which make it hard (or easy) for us
|
|
to read or use your code will be reflected in your style grade.
|
|
|
|
The existing PintOS code is written in the GNU style and largely
|
|
follows the @uref{http://www.gnu.org/prep/standards_toc.html, , GNU
|
|
Coding Standards}. We encourage you to follow the applicable parts of
|
|
them too, especially chapter 5, ``Making the Best Use of C.'' Using a
|
|
different style won't cause actual problems so long as you are self-consistent in your additions.
|
|
It is ugly to see gratuitous differences in style from one function to another.
|
|
If your code is too ugly, it will cost you points.
|
|
|
|
Please limit C source file lines to at most 80 characters long.
|
|
|
|
PintOS comments sometimes refer to external standards or
|
|
specifications by writing a name inside square brackets, like this:
|
|
@code{[IA32-v3a]}. These names refer to the reference names used in
|
|
this documentation (@pxref{Bibliography}).
|
|
|
|
If you remove existing PintOS code, please delete it from your source
|
|
file entirely. Don't just put it into a comment or a conditional
|
|
compilation directive, because that makes the resulting code hard to
|
|
read. Version control software will allow you to recover the code if
|
|
necessary later.
|
|
|
|
We're only going to do a compile in the directory for the task being
|
|
submitted. You don't need to make sure that the previous tasks also
|
|
compile.
|
|
|
|
Task code should be written so that all of the subproblems for the
|
|
task function together, that is, without the need to rebuild with
|
|
different macros defined, etc.
|
|
If you decide to do any work beyond the spec that
|
|
changes normal PintOS behaviour so as to interfere with grading, then
|
|
you must implement it so that it only acts that way when given a
|
|
special command-line option of the form @option{-@var{name}}, where
|
|
@var{name} is a name of your choice. You can add such an option by
|
|
modifying @func{parse_options} in @file{threads/init.c}.
|
|
|
|
The introduction section (@pxref{Source Code}) describes some additional high-level coding style requirements.
|
|
|
|
@comment ----------------------------------------------------------------------
|
|
|
|
@page
|
|
@node C99
|
|
@section C99
|
|
|
|
The PintOS source code uses a few features of the ``C99'' standard
|
|
library that were not in the original 1989 standard for C.
|
|
Many programmers are unaware of these features, so we will describe them.
|
|
The new features used in PintOS are mostly in new headers:
|
|
|
|
@table @file
|
|
@item <stdbool.h>
|
|
Defines macros @code{bool}, a 1-bit type that takes on only the values
|
|
0 and 1, @code{true}, which expands to 1, and @code{false}, which
|
|
expands to 0.
|
|
|
|
@item <stdint.h>
|
|
On systems that support them, this header defines types
|
|
@code{int@var{n}_t} and @code{uint@var{n}_t} for @var{n} = 8, 16, 32,
|
|
64, and possibly other values. These are 2's complement signed and unsigned
|
|
types, respectively, with the given number of bits.
|
|
|
|
On systems where it is possible, this header also defines types
|
|
@code{intptr_t} and @code{uintptr_t}, which are integer types big
|
|
enough to hold a pointer.
|
|
|
|
On all systems, this header defines types @code{intmax_t} and
|
|
@code{uintmax_t}, which are the system's signed and unsigned integer
|
|
types with the widest ranges.
|
|
|
|
For every signed integer type @code{@var{type}_t} defined here, as well
|
|
as for @code{ptrdiff_t} defined in @file{<stddef.h>}, this header also
|
|
defines macros @code{@var{TYPE}_MAX} and @code{@var{TYPE}_MIN} that
|
|
give the type's range. Similarly, for every unsigned integer type
|
|
@code{@var{type}_t} defined here, as well as for @code{size_t} defined
|
|
in @file{<stddef.h>}, this header defines a @code{@var{TYPE}_MAX}
|
|
macro giving its maximum value.
|
|
|
|
@item <inttypes.h>
|
|
@file{<stdint.h>} provides no straightforward way to format
|
|
the types it defines with @func{printf} and related functions. This
|
|
header provides macros to help with that. For every
|
|
@code{int@var{n}_t} defined by @file{<stdint.h>}, it provides macros
|
|
@code{PRId@var{n}} and @code{PRIi@var{n}} for formatting values of
|
|
that type with @code{"%d"} and @code{"%i"}. Similarly, for every
|
|
@code{uint@var{n}_t}, it provides @code{PRIo@var{n}},
|
|
@code{PRIu@var{n}}, @code{PRIx@var{n}}, and @code{PRIX@var{n}}.
|
|
|
|
You use these something like this, taking advantage of the fact that
|
|
the C compiler concatenates adjacent string literals:
|
|
@example
|
|
#include <inttypes.h>
|
|
@dots{}
|
|
int32_t value = @dots{};
|
|
printf ("value=%08"PRId32"\n", value);
|
|
@end example
|
|
@noindent
|
|
(note that the @code{%08} format string above pads the output int to 8 significant figures).
|
|
The @samp{%} is not supplied by the @code{PRI} macros.
|
|
As shown above, you supply it yourself and follow it by any flags, field width, etc.
|
|
|
|
@item <stdio.h>
|
|
The @func{printf} function has some new type modifiers for printing
|
|
standard types:
|
|
|
|
@table @samp
|
|
@item j
|
|
For @code{intmax_t} (e.g.@: @samp{%jd}) or @code{uintmax_t} (e.g.@:
|
|
@samp{%ju}).
|
|
|
|
@item z
|
|
For @code{size_t} (e.g.@: @samp{%zu}).
|
|
|
|
@item t
|
|
For @code{ptrdiff_t} (e.g.@: @samp{%td}).
|
|
@end table
|
|
|
|
PintOS @func{printf} also implements a nonstandard @samp{'} flag that
|
|
groups large numbers with commas to make them easier to read.
|
|
@end table
|
|
|
|
@comment ----------------------------------------------------------------------@page
|
|
|
|
@node Unsafe String Functions
|
|
@section Unsafe String Functions
|
|
|
|
A few of the string functions declared in the standard
|
|
@file{<string.h>} and @file{<stdio.h>} headers are notoriously unsafe.
|
|
The worst offenders are intentionally not included in the PintOS C
|
|
library:
|
|
|
|
@table @code
|
|
@item strcpy()
|
|
When used carelessly this function can overflow the buffer reserved
|
|
for its output string. Use @func{strlcpy} instead. Refer to
|
|
comments in its source code in @code{lib/string.c} for documentation.
|
|
|
|
@item strncpy()
|
|
This function can leave its destination buffer without a null string
|
|
terminator. It also has performance problems. Again, use
|
|
@func{strlcpy}.
|
|
|
|
@item strcat()
|
|
Same issue as @func{strcpy}. Use @func{strlcat} instead.
|
|
Again, refer to comments in its source code in @code{lib/string.c} for
|
|
documentation.
|
|
|
|
@item strncat()
|
|
The meaning of its buffer size argument is surprising.
|
|
Again, use @func{strlcat}.
|
|
|
|
@item strtok()
|
|
Uses global data, so it is unsafe in threaded programs such as
|
|
kernels. Use @func{strtok_r} instead, and see its source code in
|
|
@code{lib/string.c} for documentation and an example.
|
|
|
|
@item sprintf()
|
|
Same issue as @func{strcpy}. Use @func{snprintf} instead. Refer
|
|
to comments in @code{lib/stdio.h} for documentation.
|
|
|
|
@item vsprintf()
|
|
Same issue as @func{strcpy}. Use @func{vsnprintf} instead.
|
|
@end table
|
|
|
|
If you try to use any of these functions, the error message will give
|
|
you a hint by referring to an identifier like
|
|
@code{dont_use_sprintf_use_snprintf}.
|