C/C++ Unix Dev Tutorial: Maslab 2003
C/C++ Unix Dev Tutorial: Maslab 2003
Maslab 2003
Outline
C/C++ Basics
C/C++ Specifics
C/C++ Debugging
Other Tools
C/C++ Basics
Toolflow
Various files and what they represent
g++ command line usage
Modular Design & Incremental Testing
A simple wall following example
Runtime Configuration
Reducing the need for recompilation
Toolflow
compile
a.o b.o
link
exe
Compiling with g++
Use g++ to generate object files
g++ –c a.cc
Need to specify where to find include files
Called include directories
Working directory is implicitly an include directory
Use -I command line option
g++ –I/usr/local/orc/include –c a.cc
Linking with g++
Use g++ to link object files into an executable
g++ a.o b.o –o test
Link errors indicate that:
A function is declared in a header but it is not
defined in the corresponding source file
An object file has been left off the g++ command
line list
Toolflow with Libraries
a.cc a.h ex.h b.o c.o
compile ar
a.o ex.a
link
exe
Libraries
Libraries group together related object files
Maslab will provide three primary libraries
Orc library (contains orc api functions)
Debug library (contains debug “publish” functions)
Vision library (contains vision routines)
To use a library:
Include the library headers when compiling
“link in” the library .a files when linking
Libraries
Specify library location using –L option
Specify library name using –l option
-lname refers to the libname.a library
Example:
g++ a.o –L~/orc/lib –lorc –o test
Wrong order of libraries can cause link errors!
Other Command Line Options
Already mentioned
-I, -L, -l, -c, -o
Other options
-ggdb: compile with debug information
-Wall: enables all warnings
-ansi: remove non-standard gnu extensions
-D,-U: Define or undefine preprocessor name
More information at g++.gnu.org
Modular Design & Incremental Testing
Wall following example
Robot needs to:
Detect obstacles
Rotate
Move in an arc
Monolithic Design
One file, one main function, one while loop
float irTable[20] = { 1.0, 2.2 , 2.7, … }
int main() {
orc_initialize();
while (true) {
int sensorVal = orc_analog(0);
float distance = itTable[ <calcIndex> ];
if ( distance < 10 ) {
orc_motorPWM(0,0);
orc_motorPWM(1,0);
orc_motorPWM(0,100);
<sleep>
orc_motorPWM(0,100);
orc_motorPWM(1,150);
}
}
}
Monolithic Design
Eventually keep adding to this until it is
completely unmaintainable
Difficult to test
Is sensor conversion correct? Does rotation work?
Difficult to modify
Change distance threshold?
Difficult to understand
What do the PWM commands do?
Cut and paste is a really bad form of reuse
Reuse rotation code or sensor table lookup code
Modular Design
Multiple functions to do common tasks and
abstract away implementation details
readFrontSensor()
robotTurnLeft(degrees)
robotStop()
robotMoveInArc()
Group related functions into the separate files
sensor.h and sensor.cc
robotControl.h and robotControl.cc
Incrementally test each component with its own test
harness (ie its own test executable)
sensor.t.cc and robotControl.t.cc
Modular Design
Use #ifndef guards around headers
Prevents including the same header twice
Use a unique name
#ifndef TEST_H
#define TEST_H
… header code here …
#endif
Include corresponding header first in .cc
So test.cc should include test.h first
Makes sure not accidentally relying on other headers which are
not included in the .h
.h/.cc components should be self sufficient (do not rely
on externally declared values in other files)
Runtime Configuration
Runtime configuration can drastically reduce
debug time by eliminating the need to
constantly recompile
Command line options
followWalls –right –threshold 20
Configuration file
Holding sensor lookup tables
C/C++ Specifics
See Ed Faulkner’s Slides
Standard Template Library
STL
A collection of extremely useful classes
Examples
#include <string>
#include <vector>
#include <list>
#include <map>
More information at
http://www.sgi.com/tech/stl
STL Examples
Vectors
Use them just like arrays but it takes care of
dynamic memory allocation
vector vecInt(vecLength);
for ( int i = 0; i < vecLength; i++ )
cout << vecLength[i] << endl;
Lists
Linked lists of objects
list lst;
for ( int i = 0; i < vecLength; i++ )
lst.push_back( getSensorValue() );
STL Examples
Strings
Useful string stuff without strlen, strcmp
string mystring = “hello”;
string newstr = mystring + “world”;
for ( int i = 0; i < newstr.length(); i++ )
cout << newstr[i] << endl;
if ( newstr == “hello world” )
cout << “yay” << endl;
C/C++ Debugging
printf/cout method
Works better if you wrap debug statements
in either #ifdefs or if/else (with a global var)
Possibly even have multiple debug levels
The more debugging information the better
Emacs/GDB
Emacs is an excellent tool for writing code
Gnu debugger integrates nicely with emacs
Emacs/GDB
Emacs includes color formatting for C/C++
Some common commands
Type “emacs &” to start emacs in a new window
C-x C-f to load in file
C-x C-s to save a file
C-k cut from the cursor to the end of the line
C-y paste last cut at the cursor position
Emacs/GDB
Emacs/GDB
To use GDB inside of emacs
C-x 2 (splits emacs window into two)
M-x gdb (M is meta character – alt key)
Will ask for gdb command line – type in exec
Use “file execname” in gdb window
Emacs/GDB
Emacs/GDB
Use C-x space in source win to set breakpoint
GDB Common Commands
r run until breakpoint
s step to next line
n step to next line (and into function calls)
bt back trace (very useful for segfaults)
With threads, gdb will stop all threads when it
reaches a breakpoint in any one thread
Emacs/GDB
all : helloworld
clean:
rm -f *.o helloworld
Make – A Backup Target
Backup to nfs mounted team directory
datestr=`date +%Y-%m-%d_%H-%M`
backup :
tar -czf test-$(datestr).tgz .
cp test-$(datestr).tgz /nfsmnt/teamdir
F.1
checkout checkout
User User
A B
F.1 F.1
CVS – Multiple Users
F.2
commit
User User
A B
F.1 F.2
CVS – Multiple Users
F.2
commit
Conflict!
User User
A B
F.3 F.2
CVS – Multiple Users
F.2
User User
A B
F.2/3 F.2
CVS – Multiple Users
F.4
commit
User User
A B
F.4 F.2
CVS
Conflicts are rare because developers are
working on different parts of the project
Rule of thumb: always update before
commit
Informative log messages can be very
helpful tracking down bugs
CVS for Backup
Keep cvs repository in nfs mounted team dir
On athena need to access cvs through ssh
See http://www.jfipa.org/publications/CVSGuide/
Basically just set these two env variables
Export CVSROOT=“:ext:uname@athena…:/cvsrootdir”
Export CVS_RSH=“ssh”
Will need to entire password for all cvs commands