Table of Contents

Project Standards

Pass-off Queue

See Teaching Assistants page for info on how to queue for pass-off.

Time Bounds

There is a strict 60 second time bound for pass-off. The bound only includes running time; the time for compilation does not count toward the bound. Any project that completes within the time bound producing the correct output for every input is scored as passing. If a project submission falls outside the time bound then the submission fails pass-off even if it produces correct output on every input.

Submitting Project Files

Submit all .h and .cpp files needed to build the project. All files must have either a .h or .cpp extension. Any files with a .h extension must be 'included' in a file with a .cpp extension.

Package your source files (.h files and .cpp files) into a 'zip' archive. Do not use any folders. All files must be in a single 'zip' file with no folders. For example, on linux you could use a command like this:

$ zip lab1.zip *.h *.cpp
or
$ zip lab1.zip *.h *.cpp *.txt
if you have test cases to include.

Do not include object files, test cases, or other non-source files in your zip archive.

The actual submission takes place when you upload your archive to learningsuite.

g++ Compiler

You may use a number of tools to create your code for the projects in this class. When you want to pass off your project your code will need to compile and run using the g++ compiler on Linux. You can compile your code on Linux with a simple command:

$ g++ -g -Wall -Werror -std=c++17 *.cpp -o lab1
This will compile the code with all warnings enabled and create an executable file with the name lab1.

Command Line

Your program will be run with the name of the input file given on the command line. For example, your program could be run like this:

./lab1 in10.txt
Your program needs to read its input from the given input file and write its output to standard output.

Write-protected Files

The input files given to your program will be write-protected. Your program will need to open input files only for reading, not for both reading and writing. If you attempt to open a write-protected input file for both reading and writing the open will fail.

For the C++ language, this means you need to use 'ifstream' to read input files (and not use 'fstream').

Program Exit Status

Your program must run to completion with a normal exit status for any input. Do not terminate with a non-zero exit status for any input, including inputs that have errors.

For the C++ language, this means that the 'main' function needs to return a value of zero and cannot return any non-zero value.

Project Grading

Each project has a possible score of 100 points with 10 of the 100 points awarded for the programming style with the rest allocated to passing private test cases. The TAs are instructed to show enough of any failed test case to facilitate debugging. The 100 points is further divided into the equal parts depending on each project, which each part contributing 50 points.

Bonuses (incentives for early completion and correct output):

Deductions:

Partial Credit:

Project Submission/Pass-off:

Program Complexity

Your program must demonstrate good coding style and practice by separating code into functions. One way to identify functions that are too large or complicated is by measuring code complexity. Program complexity is measured by pmccabe: a program that computes cyclomatic complexity. A well-designed function usually has a complexity of 8 of lower.

The pmccabe is already installed on the lab machines, and it is easily installed on Mac OS X with Homebrew:

$ brew install pmccabe

Using pmccabe is equally easy:

$ pmccabe -v  Lexer.cpp Lexer.h
Modified McCabe Cyclomatic Complexity
|   Traditional McCabe Cyclomatic Complexity
|       |    # Statements in function
|       |        |   First line of function
|       |        |       |   # lines in function
|       |        |       |       |  filename(definition line number):function
|       |        |       |       |           |
4	4	10	7	21	Lexer.cpp(8): Lexer::getToken
2	2	28	29	35	Lexer.cpp(29): Lexer::Lexer
3	3	13	65	20	Lexer.cpp(66): Lexer::getLineNumber

The first column is the cyclometric complexity. Note that pmccabe can process any number of files simultaneously.

Output may be sorted by piping to sort (omitting the header by leaving out -v is usually best in this case):

$ pmccabe *.cpp *.h | sort -n

More options are found with

$ pmccabe -h

Program Style

Programs should make use of enumerated types and constants for descriptive names and values. Object names should be indicative of intent. Comments are always wise. Object hierarchies should convey meaning and intent as well as be consistent and sensible. Style is graded at pass-off with the TA: walk through TA selected methods explaining the code. Any program not meeting the style requirement loses points for code quality at the grader's discretion.

Some considerations for style are presented for convenience; it is not a comprehensive discussion. Write code so it can easily be understood. In particular, this means:

It also means that you follow some standard coding practice which most likely includes:

Debugging and Performance

Linux GDB

Linux provides the GDB debugger, and it is extremely useful for finding segmentation faults (i.e., crashes from invalid pointers or data corruption by writing outside of arrays and objects). Although there are several tutorials on the Internet, here is perhaps one of the most useful examples using the where command to tell you the line of code that caused the segmentation fault.

$ gdb ./lab4 
GNU gdb (GDB) Fedora 7.7.1-19.fc20
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./rules...(no debugging symbols found)...done.
(gdb)  run ../tests/rules/passoff/i40.txt 
Starting program: /users/home1/faculty/egm/tmp/cs236-datalog-interpreter/src/rules ../tests/rules/passoff/i40.txt

Program received signal SIGSEGV, Segmentation fault.
0x000000000042d288 in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.18-16.fc20.x86_64 libgcc-4.8.3-7.fc20. libstdc++-4.8.3-7.fc20.x86_64
(gdb) where
where
#0  0x000000000042d288 in main (argc=2, argv=0x7fffffffe0e8)
    at rules-main.cpp:40
(gdb) quit

The quit command exits the debugger.

OSX LLDB

Mac OSX also includes a debugger with a command line interface. This debugger is lldb. The interface is somewhat similar to gdb, but you use backtrace rather than where to get the offending line of code.

$ lldb ./lab4 test.txt
(lldb) run
Program received signal SIGSEGV, Segmentation fault.
(lldb) thread backtrace
#0  0x000000000042d288 in main (argc=2, argv=0x7fffffffe0e8)
    at rules-main.cpp:40
(lldb) quit

Valgrind (Linux and Mac OSX)

Valgrind is an excellent tool for not only memory leaks but any general issue with memory including out-of-bounds writes. Note that labs will be run through valgrind as part of the pass off proccess. This guide gives the basic outline for installing Valgrind on Yosemite. You may need to install a few packages using brew:

$brew install autoconf
$brew install automake
$brew install libtool

Valgrind generally prompts to add extra flags as needed. The starting point is

$valgrind --leak-check=yes ./lab4 test.txt

Gnu Profiler (gprof)

Profiling on Linux is accomplished using the GNU gprof. There are several tutorials on the Internet. Here is the basic process:

$ g++ -pg -std=c++11 *.cpp
$ a.out test.txt
$ gprof a.out gmon.out >& profile
$ less profile

Use a file that will give a non-trivial running time. The profiling is statistically based on sampling. There are three tables. The first table is not as useful as the second table. Following each table is an explanation of what it means. Focus on methods where time is spent.

Xcode Instruments

Xcode includes a great set of tools for performance profiling, memory allocation/deallocation analysis, and memory leak checking. You do not need to be using Xcode to use these tools. The tools are part of Xcode instruments. To access the tools, start Xcode, and then rom them menu select Xcode –> Open Developer Tool –> Instruments. There is a entire suite of Templates to choose from including Time Profiler, Memory Allocation, and Memory Leaks. For the Time Profiler choose a target, specify the command line arguments, and then hit the record button.

Xcode instruments is an easier interface for profiling, and it is more clear on how to make sense of the profiling information. It is more obvious to use effectively than GNU prof.

Visual Studio CPU Sampling

Visual Studio includes a great set of analysis tools. To accessing the profiling tool, in the top menu bar select Analyze→Performance and Diagnostics. Then choose Run CPU Sampling. This should generate a simple report to show where time is spent in your code.