Unformatted text preview:

CS 241 Spring 2007System Programming Correct C ProgramsLawrence AngraveLecture 5OverviewCompile, make, link & runImportance of writing correct programsDebug SummaryAdministrativeReminder:Turn in your MP0 before Monday 9amMultiple submits OKSMP0 QuizComment: Check out R&R Appendix AUNIX Man PagesCompilationHeader FilesLinking and librariesMacros and conditional compilationMakefilesDebugging Aids – lint, debugger, trussIdentifiers, Storage Classes and Linkage ClassesThe C compilercc [filename.c]Options include: -o [output file name]-lm to include the maths library-E to get output from preprocessor only (no compilation). For a large program you can compile a small piece at a time, and link it to larger, pre-compiled parts. To compile only, use:cc -c [filename.c]This creates object files (whose names end in .o), which can then be linked later by using them instead of the source files.The compiler works in three stages: 1. it preprocesses (replacing the #include, #define etc); 2. it compiles the preprocessed files;3. it links all of the pieces of code together into the executable program.C Compiler: LibrariesTo make the functions available to other programs, add the library tothe list of compiled files:cc -o pgm main.c file1.c g_lib.a@Follow this by ranlib g_lib.awhich organizes the file in a form that is useful for the linker. It is possible to create libraries, which are (generally large) collections of useful object code ready for linking, so they don’t need to be compiled over and over again for different programs. To do this with a set of .o files, ar ruv g_lib.a gfopen.o gfclose.o gcalloc.o.......This makes a library file called g_lib.a. ar = archive ruv = replace, update, verboseg_lib.a = output archive file nameobject files to go in the libraryConditional compilationThere is also an #ifndef, which includes lines if a name is not defined. There is also an #undef function to remove previous definitions, in order to prevent clashes.To match the #if, there is an #else; there is also #elif, which is short for else if.The preprocessor can be used to exclude code from compilation:#define DEBUG 1 /*set debug to true at top of file*/......#if DEBUGprintf(“debug: a = %d\n”, a);#endifBecause DEBUG has value 1, the printf statements will be compiled. The statements can be turned off by setting DEBUG = 0 at the start. An alternative is #ifdef DEBUG....#endifwhich will include the lines if DEBUG is defined at all at the top.Preprocessor macros with arguments#define SQ(x) ((x) * (x))will replace, e.g., SQ(a + b) by ((a + b) * (a + b)) . Note here that all of the parentheses are needed! #define min(x, y) (((x) < (y)) ? (x) : (y)) will replace an expression such asm = min(u, v)bym = (((u) < (v)) ? (u) : (v))The arguments of m can be arbitrary expressions of comparable type. @Writing large programsA large program will normally be stored as a collection of .h and .c files in its own directory. If we are developing a program called pgm, we make a header file pgm.h, which contains #includes, #defines and a list of function prototypes. All .c files should then have #include “pgm.h”at the top. Note the use of quotes rather than in < >, when you include your own header files. The compiler then looks in the current directory rather than in the directory for standard C header files.Header files in large programsOften the same header files are included in several different source code files. How to avoid multiple definitions when the header file is compiled repeatedly?Let us assume we have a header file called MyHeaderFile1.h.:#ifndef MYHEADERFILE1#define MYHEADERFILE1.... function prototypes;.... definitions; #endifThus, the material in the file is only included if it hasn’t been included already.this is only compiled ifMYHEADERFILE1 is not defined(i.e. if the header file has not been processed before)Program CorrectnessYou thought that you implement the program correct, but it crashes. Why?A common problem: memoryDo you allocate any buffer?Do you allocate enough space?Do you free it only once?Segmentation Violations and Bus Errors#include < stdio.h >main(){ char *s; s = NULL; printf("%d\n", s[0]);}(1) What will it happen?(2) Why?Importance of Writing Correct Programschar buf[80];printf(“Enter your first name”);scanf(“%s”, buf);Any problem?Problem: if the user enters more than 79 bytes, the resulting string and the string terminator \0 do not fit in the allocated variable!!Possible Fix of the Problem?char buf[80]; printf(“Enter your first name”);scanf(“%79s”, buf);.Buffer OverflowAnother Example#include <stdio.h> #include <string.h> int checkpass(void){ int x; char a[9]; x = 0; fprintf(stderr,"a at %p and\nx at %p\n", (void *)a, (void *)&x); printf("Enter a short word: "); scanf("%s", a); if (strcmp(a, "mypass") == 0) x = 1; return x; } What can be the problem?Library Function CallsTraditional UNIX – returns 0 successful, -1 unsuccessful, sets errnoPOSIX Standard Committee decides that no ‘errno’ be used. Instead: all new functions return error code Good coders handle ALL errors, not just mandatory (in the standard) ones.Error reportingperror function outputs to standard error a message corresponding to the current value of errnoNo return values of errors are defined by perror#include <stdio.h>void perror(const char * s);--------------------------strerror function returns a pointer to the system error message corresponding to the error code errnumIf successful, strerror returns a pointer to the error string#include <string.h>char *strerror(int errnum);Handling ErrorsAlways handle all errorsEither:Print error message and exit program (only in main)Return -1 or NULL and set an error indicator such as errnoReturn an error codeAll functions should report errors to calling programUse conditional compilation to enclose debugging print statementscc -DDEBUGDebug Your programDiscussion: It crashes, what can I do?Tip1: Code review by yourself and othersDo you know the problem is?char w[16];char document[4096];char docFname[128];File *fp;int main (int argc, char **argv ){ //parsing parameters … //reading document … for(i=0; i<=docLength; i++){ if(!strcmp(&(document[i]), w)){ printf(“found!\n”); return; } }}Tip2: Print Out More Debugging Info…int main (int argc, char **argv ){ //parsing parameters … //reading document … printf(“w=%s,


View Full Document

ILLINOIS CS 241 - Correct C Programs

Download Correct C Programs
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Correct C Programs and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Correct C Programs 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?