. Pointers to functions Debugging
Logistics u Mid-term exam: 18/11 Closed books List of topics – see web page Some you have to read by yourself! u Reminder: one person per exercise Copying will be severely punished Make sure your PLAB directory is not readable for other people
Pointers to Functions u C/C++ allow to have a pointer to a function int foo(int x) {…} main() { int (*func)(int); // func is a pointer to a function func = &foo; func = foo; // same int x = (*func)(7); // same as x = foo(7) }
Example: Numerical Integrator
double numericalIntegration( double a, double b, double (*func)(double), int k ) { double delta = (b - a)/k; double Sum = 0; for( double x = a+0.5*delta; x < b; x+= delta ) Sum += (*func)(x); return Sum*delta; } See NumericalIntergator.c
Example u Suppose we implement an interface of a list of ints IntList.h: struct IntList; // intListNew() // Allocates a new list IntList* intListNew(); …
Example typedef void (*funcInt)( int x, void* Data ); // intListMAPCAR(List, Func, Data ) // // Apply Func to each element of the list // void intListMAPCAR( IntList* List, funcInt Func, void* Data );
Using MAPCAR See UseList.c
“Generic” interface u MAPCAR is a uniform way of performing computations over list elements The given function provides the different functional element u Pointers to functions provide a way to write code that receives functions as arguments
Example: qsort Library procedure: qsort( void *base, size_t n, size_t size, int (*compare)(void const*, void const *) ); base – start of an array n – number of elements size – size of each element compare – comparison function
Using qsort int compareInt(void const *p, void const *q) { int a = *(int const*)p; int b = *(int const*)q; if( a < b ) return -1; return a > b; } … int array[10] = { … }; qsort( array, 10, sizeof(int), compareInt );
Testing Important aspect of programming u Careful testing of each module, reduce further bugs later on. u Automatic retesting, allow to ensure changes in code do not introduce new “features” How can we test our code?
Testing “Interpreter” u A generic code for interactive/batch test int testCmdLine( TestCmdLineCommand const*Commands, void* Data ) Arguments: Commands – list of commands Data – data shared by commands
Testing Interpreter enum TestCmdLineReturnCode { e_TestCmdLineOK, e_TestCmdLineQuit, e_TestCmdLineAbort }; typedef TestCmdLineReturnCode (*TestCmdLineFunc)(void* Data, char const* const* ArgV ); struct TestCmdLineCommand { char* m_Name; // Command Name char* m_Desc; // One line description int m_ArgNum; // # of arguments TestCmdLineFunc m_Func; // Function to call };
Building a test program See TestIntList.c
To do Read man pages FILE I/O: fopen, fclose, fprintf, fgetchar, fflush Sorting & Searching: qsort, heapsort, bsearch u Compile program supplied with this class u Run them in DDD (or gdb) set breakpoints step through program force an assert, and see what happens
Debugging Divide & Conquer 2. “Define” the bug --- reproduce it 3. Use tools: debugger & more 4. Don’t panic --- think!
Define the bug Spend the time to find out u What is wrong? u Minimal settings that lead to the error? Reproduce the wrong behavior! u Preferably on a small example
Divide & Conquer Consider possible points of failure check each one of them separately
Use Debugger Debugger u Allow to monitor run time behavior u Check where the program crashes u Put breakpoints on specific events u Trace execution of the program
Debugger Debugger can save a lot of time u Find why the program crash u Understand the context (call tree, value of variables, etc.) But… u Don’t be trapped into using debuggers all the time
Other tools u Intermediate printouts u self-checking code u asserts u Memory allocation & leaks (Tirgul)
Don’t Panic There a sensible explanation to the bug Always! Don’t rush to blame the compiler/OS Don’t attribute bugs to mysterious forces Do not try random changes to see if they resolve the program This will only introduce more bugs!