15-213/14-513/15-513 Intro to Computer Systems: Code Style
Just as important as the functionality of your code is your code's readability
to others. Therefore, in 15-213/15-513 (and other CS/ECE courses you will take), we will
be paying close attention to your coding style and taking it into consideration
when assigning grades.
Each semester the question of "What do you mean by 'good style'?" comes up. The
course staff has created this document to try and answer that question. The
most basic requirement is a consistent and logical style that makes the purpose
of your code clear to the reader. We expect you to pick something that is
readable and makes sense, and then stick to that through an entire project. The
key points we will be looking for are:
SOME QUICK THINGS TO REMEMBER:
- You should have no magic numbers in your code
- Keep naming consistent throughout the document. Usually the two naming conventions are
- Variable names and function names should not be too long but still describe what
they are being used for
- Include proper file and function headers for all files and all functions
- Comment any part of your code that you think may be difficult for a reader
to understand on their own (like if you are using a tricky formula or some shortcut to complete something)
- Other than lines that are involved with these parts of your code, you
generally don't need to have many line-specific comments.
- Remove all dead code and print statements you use for print statements
before your final submission since it makes your code more cluttered.
- Indent your code to make it easier to read and understand the control flow
- Indent within functions, if…else, switch statements
- Keep formatting consistent when dealing with functions and other statements
(like how you place your curly brackets within your functions)
- Magic numbers are numbers in your code that have more meaning than simply
their own values.
- For example, if you are reading data into a buffer by doing
fgets(stdin, buf, 256)", 256 is a "magic number" because it represents
the length of your buffer. On the other hand, if you were counting
by even numbers by doing "
for (int i = 0; i < MAX; i += 2)", 2 is not
a magic number, because it simply means that you are counting by 2s.
- You should use
const globals to clarify the meaning of magic
numbers. In the above example, doing "
#define BUFLEN 256" and then use the
BUFLEN" constant in both the declaration of "buf" and the call to "fgets".
Remember that the purpose of a header is to provide the reader with enough
information to know what your code does. It doesn't need to be very detailed
but it should have enough information such that if they were to implement
their own version based on your header, it would be similar. Here are some
questions to guide you through writing your file headers (add more info if
you want - this is just a starting point)
- What is the purpose of what you are building? For example, in cache lab,
maybe talk a bit - a few sentences - about what a cache is, what does it mean
to load/store, what are dirty bits?
- How are you building it? So discuss any data structures or specific implementation
details like for example in cache lab, you might have used some type of array based
structure to represent your cache but because this can differ between implementations,
describe a bit about how you structured your array.
- What were some design decisions? This sort of goes hand in hand with "how are you building it"
so you can combine the two but it's important to include things that might be unique to your code.
For example, in cache lab, people use different eviction policies so discussing your LRU policy
and how you have implemented your LRU (singly linked list, queue, etc) is important.
- Anything else you think the reader needs to know to understand your code without actually
reading through all of it.
- Think of this section as a summary for your code.
The purpose of these is to make sure your reader can understand what your function does
without having to actually read through the function code (a mini file header specific to
your function). Usually the format of these is as such
* @brief - explain what your function does, what is its purpose
* @params[in] - what are the inputs to your function, describe the inputs a little bit
* @params[out] - what are the outputs of your function (if your function doesn't have any,
then you can mention that there are no outputs and if you are making any internal changes
then you can briefly describe them here)
This is so important since it makes your code much readable and also
helps with debugging since you can narrow the root of the cause much
more easily. You should group your code into chunks of code that perform
similar things or have a common goal. So in terms of cache lab, you could
have a load function, a store function, an eviction function, a writeToCache
function, etc. How many functions you have is really up to you (don't have
too many otherwise that defeats the purpose) but don't put everything in
the main. Functionality should not be repeated unless absolutely necessary
(ie repeating code that could be extracted to a helper function), and
functions should not become bloated. The definition of bloated may vary
from function to function, for example your main function may necessarily
become very long, while helper functions should remain somewhat concise.
CLEANING UP MEMORY:
Whatever you allocate (malloc, calloc, realloc) should be freed by
the end of the program!
Git is a version control system. We strongly suggest that you use git, for
the reasons listed below. A portion of your style grade will be dependent on
your usage of version control.
- It helps you keep track of your progress, revert to an older working
version of your code when your current code does not function correctly,
switch between different versions of your code when you are trying out
different designs and implementations;
- It helps us correctly identify cases of academic integrity violation and
helps you defend yourself from a potential false accusation of such:
- It helps you learn a tool that is used in industries and real-life
Here are a few good tips for using git. More can be found
- Commit early and often.
- Each commit should be one and only one logical change. For
example, a bug fix and an optimization should be two separate commits. A bug
fix that requires changes in two files should not be split into two separate
- Use the editor to write a commit message (
don't supply a message via the
-m option. To configure the
editor git runs for commit messages, run
git config --global core.editor your-editor.
- Commit message should be a title of no more than 50 characters, followed
by a blank line, then by a more thorough description.
- Do not rewrite commit history. It is an important record of what
actually happened to your code.
Finally, despite there being all the git tutorials and explanations out there
in the internet, it is always a difficult task and a grave responsibility to
pick one good resource and to recommend it to a class of over 200 people. One
TA's personal recommendation is the book Pro Git that is
available for free on the
quasi-official website of git.