New User Special Price Expires in

Let's log you in.

Sign in with Facebook


Don't have a StudySoup account? Create one here!


Create a StudySoup account

Be part of our community, it's free to join!

Sign up with Facebook


Create your account
By creating an account you agree to StudySoup's terms and conditions and privacy policy

Already have a StudySoup account? Login here


by: Dr. Garrison Mohr


Dr. Garrison Mohr
GPA 3.87


Almost Ready


These notes were just uploaded, and will be ready to view shortly.

Purchase these notes here, or revisit this page.

Either way, we'll remind you when they're ready :)

Preview These Notes for FREE

Get a free preview of these Notes, just enter your email below.

Unlock Preview
Unlock Preview

Preview these materials now for free

Why put in your email? Get access to more of this material and other relevant free materials for your school

View Preview

About this Document

Study Guide
50 ?




Popular in Course

Popular in ComputerScienence

This 21 page Study Guide was uploaded by Dr. Garrison Mohr on Saturday September 26, 2015. The Study Guide belongs to CP SC 101 at Clemson University taught by Staff in Fall. Since its upload, it has received 24 views. For similar materials see /class/214269/cp-sc-101-clemson-university in ComputerScienence at Clemson University.




Report this Material


What is Karma?


Karma is the currency of StudySoup.

You can buy or earn more Karma at anytime and redeem it for class notes, study guides, flashcards, and more!

Date Created: 09/26/15
C7 C programming tips Vishal Patil Summer 2003 Contents i Introduction to Managing multi le CC project 21 Good software engineering practices 3 Using Automake and Autoconf 3 Project directory structure 32 Enabling Portablity 33 Con guration les in brief 34 A brief example 35 Understanding the con gureac le 36 Understanding the Make leam le 361 For each program 362 For each library 4 Generating build scripts 5 Build options 6 Avoiding common errors in C and C 61 Identi er clashes between source les 62 Multiply de ned symbols 63 Rede nitions7 redelarations7 con icting types 7 Effective C programming 71 Put the constant on the left in a conditional 72 Handle errors and not bugs 73 Use asserts in debug builds 74 Use exceptions 17 75 Virtual functions 18 76 Don t ignore API function return values 18 77 Be consistent 18 78 Make your code const correct 18 781 The many faces of const 18 782 Understanding the constcast operator 19 783 const and data hiding 20 8 References 21 1 Introduction This document gives a quick idea about the various aspects of software de velopment using C and C The document is in an adhoc form and lacks a proper structure and ow of information However I shall be revising the structure from time to time and as I add new information to it NOTE I HOLD NO RESPONSIBILITY FOR ANY DAMAGE OR FAILURE CAUSED BY USING THIS DOCUMENTIT IS VERY LIKELY THAT THE CONTENTS OF THE DOCUMENT MIGHT CHANGE FROM TIME TO TIME AND MIGHT EVEN BE MISTAKEN AT SOME PLACES USE THIS DOCUMENT AS PER YOUR OWN DISCRETION 2 Managing multi le CC project 21 Good software engineering practices The key to better software engineering is to focus away from developing monolithic applications that do only one job and focus on developing li braries One way to think of libraries is as a program with multiple entry points Every library you write becomes a legacy that you can pass on to other developers Just like in mathematics you develop little theorems and use the little theorems to hide the complexity in proving bigger theorems in software engineering you develop libraries to take care of low level de tails once and for all so that they are out of the way everytime you make a different implementation for a variation of the problem On a higher level you still don t create just one application You create many little applications that work together The centralized all in one ap proach in my experience is far less exible than the decentralized approach in which a set of applications work together as a team to accomplish the goal In fact this is the fundamental principle behind the design of the Unix operating system Of course it is still important to glue together the various components to do the job This you can do either with scripting or with actually building a suite of specialized monolithic applications derived from the underlying tools The name of the game is like this Break down the program to parts And the parts to smaller parts until you get down to simple subproblems that can be easily tested and from which you can construct variations of the original problem Implement each one of these as a library write test code for each library and make sure that the library works It is very important for your library to have a complete test suite a collection of programs that are supposed to run silently and return normally exit0 if they execute successfully and return abnormally assertfalse exit1 if they fail The purpose of the test suite is to detect bugs in the library and to convince you the developer that the library works The best time to write a test program is as soon as it is possible Don t be lazy Don t just keep throwing in code after code after code The minute there is enough new code in there to put together some kind of test program just do it I can not emphasize that enough When you write new code you have the illusion that you are producing work only to nd out tomorrow that you need an entire week to debug it As a rule internalize the reality that you know you have produced new work everytime you write a working test program for the new features and not a minute before Another time when you should de netly write a test suite is when you nd a bug while ordinarily using the library Then before you even x the bug write a test program that detects the bug Then go x it This way as you add new features to your libraries you have insurance that they won t reawaken old bugs Please keep documentation up to date as you go The best time to write documentation is right after you get a few new test programs working You might feel that you are too busy to write documentation but the truth of the matter is that you will always be too busy After long hours debugging these seg faults think of it as a celebration of triumph to re up the editor and document your brand spanking new cool features Please make sure that computational code is completely seperated from 10 code so that someone else can reuse your computational code without being forced to also follow your lO model Then write programs that invoke your collection of libraries to solve various problems By dividing and conquering the problem library by library with a test suite for each step along the way you can write good and robust code Also if you are developing numerical software please don t expect that other users of your code will be getting a high while entering data for your input les lnstead write an interactive utility that will allow users to con gure input les in a user friendly way Granted this is too much work in Fortran Then again you do know more powerful languages don t you Examples of useful libraries are things like linear algebra libraries gen eral ODE solvers interpolation algorithms and so on As a result you end up with two packages A package of libraries complete with a test suite and a package of applications that invoke the libraries The package of libraries is well tested code that can be passed down to future developers It is code that won t have to be rewritten if it s treated with respect The package of applications is something that each developer will probably rewrite since different people will probably want to solve different problems The effect of having a package of libraries is that C is elevated to a Very High Level Language that s closer to the problems you are solving In fact a good rule of thumb is to make the libraries suf ciently sophisticated so that each ex ecutable that you produce can be expressed in one source le All this may sound like common sense but you will be surprised at how many scienti c developers maintain just one does everything program that they perpetually hack until it becomes impossible to maintain And then you will be even more surprised when you nd that some professors don t understand why a 77simple mathematical modi cation of someone else s code is taking you so long Every library must have its own directory and Make le So a library package will have many subdirectories each directory being one library And perhaps if you have too many of them you might want to group them even further down Then there s the applications If you ve done everything right there should be enough stuff in your libraries to enable you to have one source le per application Which means that all the source les can probably go down under the same directory Very often you will come to a situation where there s something that your libraries to date can t do so you implement it and stick it along in your source le for the application If you nd yourself cut and pasting that implementation to other source les then this means that you have to put this in a library somewhere And if it doesn t belong to any library you ve written so far maybe to a new library When you are in a deadline crunch there s a tendency not to do this since it s easier to cut and paste The problem is that if you don t take action right then eventually your code will degenerate to a hard to use mess Keeping the entropy down is something that must be done on a daily basis 3 Using Automake and Autoconf In this section I shall explain managing multi le C and C projects using automake and autoconf tools These tools enable the developer to get rid of the tedium of writing complicated Makefiles for large projects and also avail portability across various platforms These tools have been speci cally designed for managing GNU projects Software developed using automake and autoconf needs to adhere to the GNU software engineering principles 31 Project directory structure The project directory is recommeded to have the following subdirectories and les 0 src Contains the actual source code that gets compiled Every library shud have it s over subdirectory Every executable shud have it s own subdirectory as well If the each executable needs only one or two source les it s sensible to keep all the source les in the same directory lib An optional directory in which you place portablity code like implementations of system calls that are not avaliable of certian plat forms 0 doc Directory containing documentation for your package 0 m4 A directory containing m4 les that you package may need to install These les de ne new autoconf macros that you should make available to other developers who want to use your libraries 0 intl Portability source code which allows your program to talk in various languages 0 po Directory containing message catalogs for your software package Automake makes it really easy to manage multidirectory source code pack ages so you shudn t be shy taking advantage of it 32 Enabling Portablity lnorder to make your CC project protable across different platforms you need to add the following lines of code to all of the source les before any include statements ifdef HAVECONFIGH include ltconfighgt endif The configh le is generated by the tools or the con gure script not quite surell and the HAVECONFIGJI ag is passed along with the D option of the compiler by the generated scripts at the time of building the project Use the autoheader utility to generate the configh le for the project 33 Con guration les in brief There are two main con guration les used by these tools 0 con gureac Used by the autoconf tool to generate plaform speci c configure script 0 Make leam Used by the automake tool to generate the Makefile for the sources present in the directory containing the Makefileam le NOTE 39 There exists a single con guredc for a project however you need to create a distinct Mdke lenm for each sub directory in the project 34 A brief example I shall explain the use of these tools with the help of a small sample project The project will involve creation of an executable le called main source main c which will call functions from a user generated library geom source circlec and stats source meanc The code for the main executable is present in the src directorry while that for the geom and stats libraries is present inside subdirectories geom and stats respectively 7inside the src directory Thus this project will cover compiling of source les7 creating static libraries and linking the libraries to create the nal executable 35 Understanding the c0n gureac le This le is used by the autoconf tool and used to generate the plaform speci c configure script The configure ac le for the example is shown below ACINIT reconf AMCONFIGHEADERConfig h AMINITAUTOMAKEtest01 ACPROGCC ACPROGRANLIB ACPROGINSTALL ACCONFIGFILESMakefile docMakefile m4Makefile srcMakefile srcgeomMakefile srcstatsMakefile libMakefile ACOUTPUT o In the above sample configure ac the parameters passed to the AMINITAUTOMAKE function namely test and O 1 represent the package name and version number respectively 0 The ACLCONFIGFILES function needs to be passed the paths of the various Makefiles which need to be generated for the various subdirectories Please note that Make leam must be present in each sub directory under the project directory 36 Understanding the Make leam le A Makefile am is a set of assignments These assignments imply the Make le7 a set of targets7 dependencies and rules7 and the Make le implies the execution of building The rst set of assignments look like this INCLUDES Igeom Istats LDFLAGS Lgeom Lstats LDADD lgeom lgeom o The INCLUDES assignment is where you insert the l ags that you need to pass to your compiler If the stuff in this directory is dependent on a library in another directory of the same package7 then the l ag must point to that directory 0 The LDFLAGS assignment is where you insert the L ags that are needed by the compiler when it links all the object les to an exe cutable o The LDADD assignment is where you list a long set of installed libraries that you want to link in with all of your executables Use the l ag only for installed libraries You can list libraries that have been built but not installed yet as well but do this only be providing the full path to these libraries If your package contains subdirectories with libraries and you want to link these libraries in another subdirectory you need to put I and L ags in the two variables above To express the path to these other subdirectories use the topsrcdir variable For example if you want to access a library under srclibfoo you can put something like INCLUDES Itopsrcdirsrcgeom LDFLAGS Ltopsrcdirsrcgeom on the Make leam of every directory level that wants access to these li braries Also you must make sure that the libraries are built before the directory level is built To guarantee that list the library directories in SUBDIRS before the directory levels that depend on it One way to do this is to put all the library directories under a lib directory and all the executable directories under a bin directory and on the Make leam for the directory level that contains lib and bin list them as SUBDIRS lib bin 361 For each program You need to declare the set of les that are sources of the program the set of libraries that must be linked with the program and optionally a set of dependencies that need to be built before the program is built These are declared in assignments that look like this mainSOURCES mainc mainLDADD lgeom lstats mainLDFLAGS Ltopsrcdirsrcgeom Ltopsrcdirsrcstats mainDEPENDENCIES geom stats 0 mainSOURCES Here you list all the quot cc7 and quot h7 les that com pose the source code of the program The presense of a header le here doesn t cause the le to be installed at pre xinclude but it does cause it to be added to the distribution when you do make dist To cause header les to be installed you must also put them in in cludeHEADERS o mainLADD Here you add primarily the l ags for linking whatever libraries are needed by your code You may also list object les which have been compiled in an exotic way as well as paths to uninstalled yet libraries 0 mainLDFLAGS Here you add the L ags that are needed to resolve the libraries you passed in mainLDADD Certain ags that need to be passed on every program can be expressed on a global basis by assigning them at LDFLAGS o mainDEPENDENClES If for any reason you want certain other targets to be built before building this program you can list them here 362 For each library There s a total of four assignments that are relevant to building libraries Eg for the lib geom these assignments can be speci ed as follows libLIBRARIES libgeoma libgeomaSOURCES circlec circleh libgeomaLIBADD circleo libgeomaDEPENDENCIES o libLlBRARlES The library name 0 libgeomaSOURCES Just like with programs here you list all the quot cc7 les as well as all the private header les that compose the library By private header le we mean a header le that is used internally by the library and the maintainers of the library but is not exported to the end user You can list public header les also if you like and perhaps you should for documentation purposes but if you mention them in includeHEADERS it is not required to repeat them a second time here libgeomaLlBADD If there are any other object les that you want to include in the library list them here You might be tempted to list them as dependencies in libgeomaDEPENDENClES but that will not work If you do that the object les will be built before the library is built but they will not be included in the library By listing an object le here you are stating that you want it to be built and you want it to be included in the library 11 o libgeomiaDEPENDENClES If there are any other targets that need to be built before this library is built7 list them here 4 Generating build scripts The following commands have to executed in order to generate the build scripts for the project 1 libtoolize 2 aclocal 3 autoheader 4 autoconf 5 touch README AUTHORS NEWS ChangeLog Required for GNU software adherence 6 automake a The execution of the above four commands generates the configure in the top directory and Makefile scripts in the top directory as well as each of the sub directories 5 Build options You need to run the configure script before building the project using make After successfully running the configure script the following options as avaliable for make 0 make Builds the project and creates the executables and libraries 0 make clean Cleans the project ie removes all the executables 0 make install Builds and installs the project ie the executable is copied in the pre xbinheaders in pre xinclude and libraries in pre xlib where prefix is usually usrlocal 0 make uninstall Uninstalls the project ie removes the les added to pre xbin7 pre xinclude and pre xlib directories 0 make dist Creates a distribution of the project ltpackage namegt ltversiongttargz le of the project 12 6 Avoiding common errors in C and C 61 Identi er clashes between source les In C variables and functions are by default public so that any C source le may refer to global variables and functions from another C source le This is true even if the le in question does not have a declaration or prototype for the variable or function You must therefore ensure that the same sym bol name is not used in two different les If you don t do this you will get linker errors and possibly warnings during compilation One way of doing this is to pre x public symbols with some string which depends on the source le they appear in For example all the routines in gfxc might begin with the pre x gfo If you are careful with the way you split up your program use sensible function names and don t go overboard with global variables this shouldn t be a problem anyway To prevent a symbol from being visible from outside the source le it is de ned in pre x its de nition with the keyword static This is useful for small functions which are used internally by a le and won t be needed by any other le 62 Multiply de ned symbols A header le is literally substituted into your C code in place of the in clude statement Consequently if the header le is included in more than one source le all the de nitions in the header le will occur in both source les This causes them to be de ned more than once which gives a linker error see above Solution don t de ne variables in header les You only want to declare them in the header le and de ne them once only in the appropriate C source le which should include the header le of course for type checking The distinction between a declaration and a de nition is easy to miss for beginners a declaration tells the compiler that the named symbol should exist and should have the speci ed type but it does not cause the compiler to allocate storage space for it while a de nition does allocate the space To make a declaration rather than a de nition put the keyword extern before the de nition So if we have an integer called counter which we want to be publicly 13 available we would de ne it in a source le one only as int counter7 at top level and declare it in a header le as extern int counterg 63 Rede nitions redelarations con icting types Consider what happens if a C source le includes both ah and bh and also ah includes bh which is perfectly sensible bh might de ne some types that ah needs Now the C source le includes bh twice So every de ne in bh occurs twice every declaration occurs twice not actually a problem every typedef occurs twice etc In theory since they are exact duplicates it shouldn t matter but in practice it is not valid C and you will probably get compiler errors or at least warnings The solution to this problem is to ensure that the body of each header le is included only once per source le This is generally achieved using preprocessor directives We will de ne a macro for each header le as we enter the header le and only use the body of the le if the macro is not already de ned In practice it is as simple as putting this at the start of each header le ifndef FILENAMEH define FILENAMEH and then putting this at the end of it endif replacing FlLENAMELH with the capitalised lename of the header le using an underline instead of a dot Some people like to put a comment after the endif to remind them what it is referring to eg endif ifndef FILENAMEH Personally I don t do that since it s usually pretty obvious but it is a matter of style You only need to do this trick to header les that generate the compiler errors but it doesn t hurt to do it to all header les 7 Effective C programming 71 Put the constant on the left in a conditional We ve all experienced bugs like this while continue TRUE this loops forever This type of problem can be solved by putting the constant on the left so if you leave out an in a conditional you will get a compiler error instead of a program bug because constants are non lvalues of course while TRUE continue compile error 72 Handle errors and not bugs There are lots of error conditions that happen in the normal life of a program For instance le not found out of memory or invalid user input You should always handle these conditions gracefully by re prompting for a lename by freeng memory or telling the user to quit other applications or by telling the user there is an error in his input respectively However there are other conditions which are not real error conditions but are the result of bugs For example say you have a routine which copies a string into a buffer and no one is supposed to pass in a NULL pointer to the routine You do not want to do something like this void CopyStringchar szBuffer int nBufSize if NULL szBuffer return quietly fail if NULL pointer else strncpyszBuffer quotHelloquot nBufSize l Also don t do something like this some extremely fault tolerant systems may be able to justify this but 99 of applications can t void CopyStringchar szBuffer int nBufSize if NULL szBuffer cerr ltlt quotError NULL pointer passed to CopyStringquot ltlt endl else strncpyszBuffer quotHelloquot nBufSize lnstead do something like this void CopyStringchar szBuffer int nBufSize assertszBuffer complains and aborts in debug builds strncpyszBuffer quotHelloquot nBufSize In a release build if the user passes in a NULL pointer this will crash But rather than think 77I never want my application to crash therefore I will test all pointers for NULL think 77I never want my applications to crash therefore I will put in asserts and nd bugs that result in NULL pointers being passed to routines so I can x them before I ship this software 73 Use asserts in debug builds Use asserts liberally in debug builds You normally don t want to put assert code in release builds because you don t want the user to see your bug messages ANSI C that s lSO for you purists provides assertion functions in 1asserthL if the symbol NDEBUG is de ned somewhere before 1asserthL is included then assert will have no effect Otherwise it will print out a diagnostic message and abort the program if its argument evaluates to FALSE Since 0 FALSE you can use assert on pointers to test them for non NULL void myFunctionchar stoo assertstoo same as assertNULL stoo 74 Use exceptions Use the trythrowcatch mechanisms in C they are very powerful Many people implement an exception class7 which they use for general error reporting throughout their program class ProgramException pass in a pointer to string make sure string still exists when the PrintError method is called ProgramExceptionconst char const szErrorMsg NULL if NUL szErrorMsg mszMsg quotUnspecified errorquot else mszMsg szErrorMsg void PrintError cerr ltlt mszMsg ltlt endl void OpenDataFileconst char const stileName assertstileName if NULL fopenstileName quotrquot throw ProgramExceptionquotFile not foundquot int mainvoid try OpenDataFilequotfoodatquot catch ProgramException e ePrintError return EXITFAILURE return EXITSUCCESS 7 5 Virtual functions In C virtual functions are used for enabling Polymorphism Following two important points need to noted while using virual functions 0 A function declared as virtual in the base class shud to be declared as virtual in the derived class as well 0 A class which has a member function declared as virtual needs to have it s destructor to be de ned as virtual as well This is required for proper calls to the destructor up the class hierarchy 76 Don7t ignore API function return values Most API functions will return a particular value which represents an error You should test for these values every time you call the API function If you don t want want to clutter your code with error testing then wrap the API call in another function do this when you are thinking about portability too which tests the return value and either asserts handles the problem or throws an exception The above example of OpenDataFile is a primitive way of wrapping fopen with error checking code which throws an exception if fopen fails 77 Be consistent Be consistent in the way you write your code Use the same indentation and bracketing style everywhere If you put the constant on the left in a condi tional do it everywhere If you assert on your pointers do it everywhere Use the same kind of comment style for the same kind of comments If you are the type to go in for a naming convention like Hungarian notation then you have to stick to it everywhere Don t do int iCount in one place and int nCount in another 78 Make your code const correct 781 The many faces of const const int x constant int 18 x 2 illegal can t modify x const int pX changeable pointer to constant int pX 3 illegal can t use pX to modify an int pX ampsome0therIntVar legal pX can point somewhere else int const pY constant pointer to changeable int pY 4 legal can use pY to modify an int pY ampsome0therIntVar illegal can t make pY point anywhere else const int const pZ const pointer to const int pZ 5 illegal can t use pZ to modify an int p2 ampsome0therIntVar illegal can t make pZ point anywhere else The const keyword is more involved when used with pointers A pointer is itself a variable which holds a memory address of another variable it can be used as a 77handle77 to the variable whose address it holds Note that there is a difference between 77a read only handle to a changeable variable77 and a 77changeable handle to a read only variable 782 Understanding the consticast operator const int x 4 x is const it can t be modified const int pX XIX you can t modify x through the pX pointer cout ltlt x ltlt endl prints quot4quot int pX2 constcast lt int gt pX explicitly cast pX as nonconst pX2 3 result is undefined cout ltlt x ltlt endl who knows what it prints The consticast operator is more speci c than normal type casts because it can only be used to remove the const ness of a variable7 and trying to change its type in other ways is a compile error For instance7 say that you changed X in the above example to an double and changed pX to doublequot However the variable pX2 is casted as int pX2 int pX explicitly cast pX as nonconst The code would still compile7 but pX2 would be treating it as an int It might not cause a problem because ints and doubles are somewhat similar7 but 19 the code would certainly be confusing Also if you were using user de ned classes instead of numeric types the code would still compile but it would almost certainly crash your program If you use constcast you can be sure that the compiler will only let you change the const ness of a variable and never its type 783 const and data hiding In C when a member function returns a pointer which points to its member variable there exists a possibility of the pointer address or the pointer value getting modi ed This problem can be overcome by using the const keyword An example illustrating this idea is given below class Person public Personchar szNewName make a copy of the string mszName strdupszNewName quotPersonO delete mszName const char const GetNameO const return mszName private char mszName In the above class the GetName member function returns a pointer to the member variable mszName To prevent this member variable from getting accidently modi ed the GetName has been prototyped to return a constant pointer pointing to a constant value Also the const keyword at the end of the function prototype states that the function does not modify any of the member variables 8 References 0 httpwwwgmonlinedemoncoukcsceneCS2CS2 O1htm1 o httpautotoolsetsourceforgenettut0rialhtml


Buy Material

Are you sure you want to buy this material for

50 Karma

Buy Material

BOOM! Enjoy Your Free Notes!

We've added these Notes to your profile, click here to view them now.


You're already Subscribed!

Looks like you've already subscribed to StudySoup, you won't need to purchase another subscription to get this material. To access this material simply click 'View Full Document'

Why people love StudySoup

Bentley McCaw University of Florida

"I was shooting for a perfect 4.0 GPA this semester. Having StudySoup as a study aid was critical to helping me achieve my goal...and I nailed it!"

Anthony Lee UC Santa Barbara

"I bought an awesome study guide, which helped me get an A in my Math 34B class this quarter!"

Steve Martinelli UC Los Angeles

"There's no way I would have passed my Organic Chemistry class this semester without the notes and study guides I got from StudySoup."

Parker Thompson 500 Startups

"It's a great way for students to improve their educational experience and it seemed like a product that everybody wants, so all the people participating are winning."

Become an Elite Notetaker and start selling your notes online!

Refund Policy


All subscriptions to StudySoup are paid in full at the time of subscribing. To change your credit card information or to cancel your subscription, go to "Edit Settings". All credit card information will be available there. If you should decide to cancel your subscription, it will continue to be valid until the next payment period, as all payments for the current period were made in advance. For special circumstances, please email


StudySoup has more than 1 million course-specific study resources to help students study smarter. If you’re having trouble finding what you’re looking for, our customer support team can help you find what you need! Feel free to contact them here:

Recurring Subscriptions: If you have canceled your recurring subscription on the day of renewal and have not downloaded any documents, you may request a refund by submitting an email to

Satisfaction Guarantee: If you’re not satisfied with your subscription, you can contact us for further help. Contact must be made within 3 business days of your subscription purchase and your refund request will be subject for review.

Please Note: Refunds can never be provided more than 30 days after the initial purchase date regardless of your activity on the site.