Style Guide
When you are modifying an existing program, the first and foremost rule of good coding style is that the style of your code, e.g., its indentation, should match the style of the surrounding code. In effect, it should not be obvious to a reader where different people have edited the code. Also, keep in mind that if you consistently indent your code, it will make it easier for someone else (i.e., the graders) to understand your code.
Clang-format
Each of the assignments includes a format
rule in the Makefile.
You can reformat your code to mostly conform to this style guide by
running:
make format
This will run clang-format to format the code. The VSCode C/C++ extension also uses clang-format to format C code. So, you can also format your code directly within VSCode — using Ctrl+Shift+I, for example. Note that you likely were prompted to install this extension the first time you opened a C file, if it was not already installed.
Note that while clang-format
brings the code more in line
with the style guide, you still need to read and understand the guide.
It is your responsibility to perform whatever additional formatting is
needed to conform with the guide below.
Specific Guidelines
Any comment that does not appear on the same line as code must consist of one or more complete sentences.
/* * VERY important single-line comments look like this. */ // Most single-line comments look like this. /* A single-line comment can also look like this. */ /* * Multi-line comments look like this. They should consist of real * sentences. Fill them so that they look like real paragraphs. */
Include directives come first. More precisely, if operating system header files (i.e., sys/*.h) are used, they come first, followed by a blank line. Include directives for C standard library header files come next. These include directives should be sorted alphabetically by file name. If application header files (e.g., csapp.h) are used, they come last, preceded by a blank line.
#include <sys/types.h> // Operating system files in angle brackets #include <assert.h> // C standard library files in angle brackets #include <math.h> #include <stdio.h> #include <string.h> #include "csapp.h" // Application files in double quotes
Major structures should be declared near the top of the file in which they are used, or in separate header files if they are used in multiple source files.
Try to align the field names and any comments describing them in the structure definition.
struct foo { struct foo *next; // List of foo struct mumble amumble; // Description of amumble int bar; // Description of bar };
All functions are prototyped somewhere, either in a header file or a source file.
Function prototypes for private functions (i.e., functions not used elsewhere) go near the top of the source file. Private functions should be declared static.
All functions should have a comment that describes what the function does and states any requirements of the function. In addition, the comment should describe the parameters and return value, if any.
/** * Searches through the directories listed in the PATH environment variable to * find the first occurrence of the specified executable. If the executable * is found, its full path and executable permissions are printed to standard * output. If the executable is not found, a message is printed to standard * output indicating that the executable was not found. * * @param executable The name of the executable file to find * @return Returns 0 on success, 1 if the executable file is not found, or 2 if * an error occurs. */ int find(const char *executable) {
The function type should be on a line by itself preceding the function. The opening brace of the function body should be on a line by itself.
static char * function(int a1, int a2, float fl, int a4) {
There is a space after keywords (if, while, for, return, switch).
There are no spaces after function names. Commas have a space after them. Semicolons not at the end of a line have a space after them. There are no spaces after `(' or `[' or preceding `]' or `)' characters.
error = function(a1, a2); if (error != 0) exit(error);
Unary operators do not require spaces, but binary operators do. Do not use parentheses unless they are required for precedence, or unless the statement is confusing without them.
a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1; k = !(l & FLAGS);
Each level of indentation should consist of 8 character positions. By default, in most text editors, including nano, a tab character skips ahead to the next tab stop, which is the next character position that is a multiple of 8. Thus, you may use the tab character instead of multiple spaces to easily indent your code.
Statements that would exceed 80 characters must be wrapped. In other words, the statement should occupy multiple lines. The continuation lines of a wrapped statement are indented an extra four character positions over the line being wrapped. If you have to wrap a long statement, put the operator at the end of the line.
while (cnt > 20 && this_variable_name_is_too_long && ep != NULL) z = a + really + long + statement + that + needs + two + lines + gets + indented + four + spaces + on + the + second + and + subsequent + lines;
Closing and opening braces go on the same line as the keyword (if, else, while, for, switch). Braces that are not necessary may be left out.
if (test) stmt; else if (bar) { stmt; stmt; } else stmt;
When defining variables in functions, there are two styles: classic and modern. In the classic style, all variables are defined at the beginning of the function. In contrast, in the modern style, a variable is defined when it is first used. You may use either style.
When using the classic style, define variables sorted by the size of the type, then in alphabetical order. Note that this means that arrays of and pointers to a particular type should be grouped with objects of that type. Defining multiple variables per line is okay. However, the line must not exceed the 80 character limit. Repeat the type on the continuation line.
struct a_32_byte_struct alfa, *bravo; double charlie, *delta; int *echo, foxtrot, **golf; char hotel, *india, juliett, kilo[16], lima; char mike, november, oscar, **papa;
When using the modern style, both the variable's definition and the first assignment to the variable take place in the same statement. Try to minimize the scope of the variable.
long function(long array[], int length) { long sum = 0; for (int i = 0; i < length; i++) { long multiplier = random(); sum += multiplier * array[i]; }
Portions of this style guide have been borrowed from STYLE(9)
from the FreeBSD Kernel Developer's Manual. The original copyright
notice is reproduced below:
Copyright 1992-2012 The FreeBSD Project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project.