Coding Guidelines
How to not shoot yourself in the foot
Richard Peschke | Coding Guidelines | | Page 1 0. Use the right Tools >Use version control! >Use an IDE! >Use a debugger!
Richard Peschke | Coding Guidelines | | Page 2 Richard Peschke | Coding Guidelines | | Page 3 Backup
Richard Peschke | Coding Guidelines | | Page 4 General Things
>C++ is most likely the worst language to start programming >We have not chosen it because it is such a nice language >If you are new to >programming start with: . Python, JavaScript or Matlab . a scripting language! . If you are teaching C++ >“STOP TEACHING C”
Richard Peschke | Coding Guidelines | | Page 5 Performance
>Why C++? Because Performance! >Cell phones: How to save energy? Performance! >Computer farm: How to save money? Performance!
>1% of performance boost saves Facebook 100k€ in electricity Source: Ima Dethi-Sup
Richard Peschke | Coding Guidelines | | Page 6 Performance
>Don’t use new >Don’t use Objects features . Objects have the overhead . Fortran is the peak of constructing and deleting of computer science >Don’t use garbage evolution collection >Functions are evil . Modern computer have . Copy all code in enough memory one function to >Exceptions are avoid jumps dangerous >Comments . Don’t write errors . Every three lines
Richard Peschke | Coding Guidelines | | Page 7 Stop doing Cargo Cult Programming
Richard Peschke | Coding Guidelines | | Page 8 Why do I care so little about Performance?
>For the next two years All your programs are just “Hello World” programs They do not need to run fast! Understanding how they work is the most important thing
You are programming for the trash bin! (90% of the time)
Richard Peschke | Coding Guidelines | | Page 9 How do you get Performance?
>By not using your code! >If the performance has Use libraries to come from your code Copy examples from the internet >If you have a problem, somebody else had it before you!
Richard Peschke | Coding Guidelines | | Page 10 Refactoring
Requirements >Readability >Use an environment where you can easily jump through your code . Two button presses to get to the definition of something is to much . Creating function definitions from declaration should not be more than two buttons . The environment needs to work with symbols and not with Text . Do not use regex to search in your code >Automated Build system . Getting to the line where an error occurred must not be more expensive than one click
Richard Peschke | Coding Guidelines | | Page 11 Readability
Understanding your Code
Refactoring Modular Design Documentation Testability
Reuse Sharing Correctness
Richard Peschke | Coding Guidelines | | Page 12 Performance How to get your code nice and clean
>We are no professionals we are just physicists! >Nobody writes bad code on purpose! >Nobody writes good code alone!
Richard Peschke | Coding Guidelines | | Page 13 How to measure code Quality?
Industry standard: >someValue wtf/min >HEP: >100*someValue wtf/min >HEP solution: don’t have code reviews at all
Richard Peschke | Coding Guidelines | | Page 14 How to start
Before you start the computer >Write down what your code needs to do (in English or your native language) >Find specific tasks >Find the dependencies . (tasks, data, handles, hardware …) . What belongs together >Speak with somebody >Somebody else!
Richard Peschke | Coding Guidelines | | Page 15 What is Programming?
Debugging Documenting
Planning
Testing Coding
Code Review
Richard Peschke | Coding Guidelines | | Page 16 Organizational Stuff
Organizational: >Use a version control system Git SVN >Use automatic build system . Cmake . make . MSBuild
Richard Peschke | Coding Guidelines | | Page 17 Git
Richard Peschke | Coding Guidelines | | Page 18 CMake
Richard Peschke | Coding Guidelines | | Page 19 Design Styles
Keep it Simple! >Code must be human readable! . Code that only you can read is wrong! Even if it gives reasonable results! >Correct is better than fast! >Use self-explaining names >One entity has one purpose . Every function should do exactly one thing Stay on one Level of abstraction . Do not reuse variables . Give classes specific tasks
Richard Peschke | Coding Guidelines | | Page 20 Easy things to avoid
>Copy and paste >Ambiguous names . If you need it twice make it a . Variable names do not need to be short function . Auto completion was invented in 1988 > >Magic numbers Raw Pointer . . Make it a variable, give it a Use Shared_ptr . meaningful name! Do you really need a pointer? > >Global variables Don’t use c style cast . Use dynamic_cast or static_cast . You never need them >C style arrays . Use vector! >Avoid to write loops . Use algorithms
Richard Peschke | Coding Guidelines | | Page 21 Comments
Comments can be gossip
Richard Peschke | Coding Guidelines | | Page 22 Comments
Bad >Don’t rewrite your code in pseudo code in comments . Expect that who ever reads your code knows C++ better than you (maybe even better than English)
Richard Peschke | Coding Guidelines | | Page 23 Comments
Void f1(){ … 1000 lines of code Bad /* Check to see if the employee is eligible for full benefits*/ >You want to say something if((employee.flags & HOURLY_FLAG) && in English what you can’t (employee.age > 65)) say in C++ } Learn programming >Your code is a mess and Do it like this: if(employee.isEligibleForFullBenefits( )) you want to give some hints what it does Learn programming
Richard Peschke | Coding Guidelines | | Page 24 Comments
Void MyMonsterFunctionWithMoreThan1000lines(){ // declaring some parameter // which i need later for sure Bad ... 100 lines // Initilizing Variables >You want to say something ... 100 lines // using Variable in English what you can’t ... 100 lines say in C++ //clean up } Learn programming >Your code is a mess and Do it like this: you want to give some hints Void MyFunctionWithAUsefulName(){ what it does Object myObjectWithAMeaningfullName; Learn programming myObjectWithAMeaningfullName.Init();
useMyObjectForASpecificTask( myObjectWithAMeaningfullName) maybeDoSomethingElseWithIt( myObjectWithAMeaningfullName)
} Richard Peschke | Coding Guidelines | | Page 25 Comments
Good /*True if collection is the default collection for the given type. This implies that the collection is >At the library, program, or complete and unambigous. Convenient method function level, describe that checks bit BITDefault of the flag word Implements EVENT::LCCollection.*/ what bool isDefault ( ); >Inside the library, program, /* We're going to use newton's method to find the root of a number because there is no analytical or function, describe how way to solve these equations */ >At the statement level,
/* We need to divide items by 2 here because describe why they are bought in pairs*/ cost = items / 2 * storePrice;
Richard Peschke | Coding Guidelines | | Page 26 Magic Numbers
What are magic numbers? Why they are evil? >Plain numbers that appear >You can’t search for them! somewhere in your source >You can’t make changes code >They contain unknown
> HANDLE hSerial; information > hSerial = reateFile("COM1", > GENERIC_READ | GENERIC_WRITE, > 0, > 0, > OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL, 0); >What do all the zeroes mean?
Richard Peschke | Coding Guidelines | | Page 27 How to avoid magic numbers
On library level >If your function only accepts certain parameters Provide them alongside with the function >Think about using enums
Richard Peschke | Coding Guidelines | | Page 28 How to avoid magic numbers inside a library or a program >Why is it different from global variables? Because they are const! >Use const values over preprocessor definitions . They are type safe >Group them in namespaces >Comment them where you define them!
Richard Peschke | Coding Guidelines | | Page 29 How to avoid magic numbers
Inside a function
… >Your are using the wrong class or type These are >Use specific types for magic Numbers specific tasks
…
Richard Peschke | Coding Guidelines | | Page 30 Identifying Magic Numbers
M agi f1(105);c Nu RAW Strings are Magic numbers too! mbe r >They are not checked by the f1({ 105,32,97, compiler r >Hard to search for 109,32,100,be um >Hard to maintain N ic117,109,98,0}); >Almost impossible to change ag M afterwards f1((char*)new int[] { 105,32,97, 109,32,100,
117,109,98,0});r be um N gic f1("i amM astupid");
mber Magic Nu
Richard Peschke | Coding Guidelines | | Page 31 Magic Numbers (Real Live Experience)
e r m yTTree-> D raw ( e h "m yAxisW ithRidiculousLongN am e w y : r m yO therAxisW ithRidiculousLongN am e e v > > e m yFancyO utputHistogram ", s r "M ySuperAw esom eCutVariable > 5 e & & b M ySuperAw esom eCutVariable < 7“ m ,"CO LZ“ u n ) ic g a M
Richard Peschke | Coding Guidelines | | Page 32 Where is the problem?
>TTrees are generic container The types and names are not provided by the library >Getting objects by there names ( as string) is a common approach for any generic container (zB. file I/O) >Dynamic typed languages overcome the problem by creating during runtime a handler object
N o t p o ss ib le in C + +
Richard Peschke | Coding Guidelines | | Page 33 Magic Numbers (Real Live Experience)
Create your own custom class class M yCustom Tree { public: No Magic (numbers) TAxis_t G etAx1(); Anymore TAxis_t G etAx2(); private: TTree m _tree; }; TAxis_2D _t operator& (TAxis_t, TAxis_t); TAxis_2D _w ith_h2_t operator>> (TAxis_2D _t, const TH 2& ); Long_t D raw (TD raw Axis); int m ain(){ M yCustum Tree m yTree; TH 2* h2 = new TH 2D (… ); D raw ((m yTree.G etAx1()& m yTree.G etAx2())> > *h2); return 0; } Magic is heresy
Richard Peschke | Coding Guidelines | | Page 34 The Three Base Types in C++
>Float (double…) >Insanity (aka unsigned) Use: Use: . To store quantities which can warry . If you need to express your insanity in over many orders of magnitude source code OR: . If you are lazy . Default Type for beginners > Int (long int …) Use: . You need a counter . When you know during compile time what range of values to expect . When Performance really mattes to you (experts stuff)
Richard Peschke | Coding Guidelines | | Page 35 Types and why do we care
void add_date(int, int, int); >How do I use this thing? add_date(10, 11, 12); >What date is it? . 10.11.2012? . 10/11/2012? . 2010-11-12?
Richard Peschke | Coding Guidelines | | Page 36 Types and why do we care
void add_date(Day_t, Month_t, Year_t); add_dateCom (10, 11, 12); piler E add_date(Month_trror (10), Day_t(11), Year_t(12)); Compile add_date(Day_t (10), Month_tr Er(11),ror Year_t(12)); add_dateCompiling(10_dd, 11_mm,Working 12_yy); Doing the right thing
User defined literals:
Richard Peschke | Coding Guidelines | | Page 37 Types: Summery
>Treat build in types (int/double/string) as Use the compiler radioactive . They don’t carry any information >Use typedefs (renaming of types) to show an intention >Use custom container classes to have the compiler check your code
Richard Peschke | Coding Guidelines | | Page 38 Give a class one specific task
In the real world objects are build of smaller object. Why not in your code?
Richard Peschke | Coding Guidelines | | Page 39 examples
Richard Peschke | Coding Guidelines | | Page 40 Use Modern Code!
H ow h ard ca n Example: “for loop” it b e? Vector
cout< Richard Peschke | Coding Guidelines | | Page 41 RAII Richard Peschke | Coding Guidelines | | Page 42 RAW Pointer There might be a leak somewhere Richard Peschke | Coding Guidelines | | Page 43 Responsibility Resource Management What are resources? what do you do with them >Memory >Require them >Ports >Work with them >Files >Release them >… >Coping what. your you computer can’t hasdo: a limited amount of memory (you can copy the elements in memory but not the memory) Richard Peschke | Coding Guidelines | | Page 44 Example code: Memory Allocation D D Staticallyo Dynamically Variable number of n o elements (good) Fixed number of elements voidn f2(int elem ents){ void’ f1(){ (bad) t int *’i= new int[elem ents]; int i[100]; … t w Nobody knows where it ends … for (autow e= i;e!= i+ elem ents(bad);++ e) r { r for (autoit & e:i) cout< < *e< < endl; e it { } e delete[] i; t cout< Use a container class Variable number of elements void f3(int elem ents){ (good) vector< int> i(elem ents); … for (auto& e:i) { It knows its own size cout < < e < < endl; (good) } } Automatic clean up (very good) Richard Peschke | Coding Guidelines | | Page 46 How does it work? class Vector{ public: Vector(int Num berOfElem ents){ m _size_of_array= Num berOfElem ents; >Dynamic memory m _pointer= new int[m _size_of_array]; } allocation inside the int* at(int elem ent){ object return m _pointer+ elem ent; } >Provides access to the int size(){ Array return m _size_of_array; } >The destructor calls the ~ Vector(){ delete operator delete[] m _pointer; } >The object store the private: pointer to the array and int* m _pointer; int m _size_of_array; its size }; Richard Peschke | Coding Guidelines | | Page 47 Responsibility Resource Acquisition Is Initialization RAII Example of an RAII class: Why should you do it? >You can’t forget to release the resource >Exception Safe >Value Semantics >Raw pointers are just an accident that waits to happen Use RAII classes such as Smart pointers proactive Richard Peschke | Coding Guidelines | | Page 48 Clean interfaces through RAII Without RAII processor* getProcessor(const char* N am e); processor* getReference2Processor(const char* N am e); > O w ned objects and optional references to objects have the sam e type With RAII unique_ptr< processor> getProcessor(const char* N am e); processor* getReference2Processor(const char* N am e); > O bject ow nership is indicated by the type type safe Richard Peschke | Coding Guidelines | | Page 49 Clean interfaces through RAII unique_ptr< processor> ow nedO bject processor ow nedO bject processor* optionalReference processor& nonO ptionalReference Richard Peschke | Coding Guidelines | | Page 50 Functions: What do you do when you write a function that is 1000 lines long? You are doing something wrong Richard Peschke | Coding Guidelines | | Page 51 Code Reuse void fun_A() { void fun_B() { if (pi= = 5) if (pi == 3) { { //1000 lines of very important code //1000 lines of very important code } } if (e == 3) if (e == 2) { { //////////////////////////////////////////////////// //////////////////////////////////////////////////// // starting doing stupid TASK A //////////////// // starting doing stupid TASK A //////////////// //////////////////////////////////////////////////// //////////////////////////////////////////////////// //1000 lines of very important code //1000 lines of very important code //////////////////////////////////////////////////// //////////////////////////////////////////////////// // finishing stupid TASK A //////////////// // finishing stupid TASK A //////////////// /////////////////////////////////////////////////// /////////////////////////////////////////////////// } } } } Richard Peschke | Coding Guidelines | | Page 52 Code Reuse void fun_A() >Make “Task A” a function >Call the function if(pi= = 5) Do … if(e= = 3) Task A void fun_B() if(pi= = 3) Do … if(e= = 2) Task A Unique code Shared code Richard Peschke | Coding Guidelines | | Page 53 Code Reuse void fun_c() { void fun_d() { std::vector< int> vec = getVector(); std::vector< int> vec = getVector(); for (auto& e: vec) for (auto& e : vec) { { /////////////////////////////////////////////////// //////////////////////////////////////////////////// // starting doing stupid TASK C /////////////// //== = = > starting doing stupid TASK D <= = = = ////////// /////////*********************************///////// /////////*********************************////////// //1000 lines of very important code //1000 lines of very important code /////////*********************************///////// /////////*********************************////////// // finishing stupid TASK C //////////////// //== = = > finishing stupid TASK D <= = = = /////////// /////////////////////////////////////////////////// //////////////////////////////////////////////////// } } } } Richard Peschke | Coding Guidelines | | Page 54 Code Reuse: Generic Programming void fun_c() >Function pointer . Signal/Slot (QT/ROOT) for(auto& e:vec) Task C . Function hooks >Inheritance >Templates void fun_d() for(auto& e:vec) Task D Unique code Shared code Richard Peschke | Coding Guidelines | | Page 55 Generic Programming: Inheritance class base{ class Task_C :public base { public: public: void ProcessVector() { virtual void ProcessElem entOfVector(int) override final std::vector< int> vec = getVector(); { for (auto& e : vec){ // Task C ProcessElem entOfVector(e); } } }; } virtual void ProcessElem entOfVector(int) = 0; }; Base::ProcessVector() Task_C::ProcessElem entOfVector(int) Unique code Shared code Richard Peschke | Coding Guidelines | | Page 56 Lets Talk about the Pit Richard Peschke | Coding Guidelines | | Page 57 Where is the Pit? Your goals in live This is the Pit Richard Peschke | Coding Guidelines | | Page 58 One function has one task! Every function should stay on one level of abstraction D Done! OR: A B D O A S B T O N Richard Peschke | Coding Guidelines | | Page 59 What you wanted to do H i Loop g Read- Find- h Display Line Once l e v If(object is empty){ If (Keyword found){ e L n Display(input) o next Task i Stop t c a r t s } else { Stop b next Task A Read_from(Object) } else { next w Continue o Task Continue L } Continue } Richard Peschke | Coding Guidelines | | Page 60 What was written > The Levels of Abstractions are totally mixed up Loop Welcome to your MC Escher Program While(!stopped){ } Richard Peschke | Coding Guidelines | | Page 61 What was written > The Levels of Abstractions are totally mixed up Loop Enjoy your debugging! While(!stopped){ } Richard Peschke | Coding Guidelines | | Page 62 How could It look like In Actual Code In Pseudo Code void readFile(const char* nam e, const char* keyW ord) { void readFile() { // initialize init(); // open file auto inFile = fileReader(nam e); loop{ if (!inFile.isValid()) readLine(); throw FileIsInvalid; CheckForKeyW ord(); D isplay(); // Loop } w hile (true) { Replace Loop Condition end(); //clean up if needed // begin file reader } if (inFile.EndO fFile()) break; auto line = inFile.getLine(); // end file reader // Begin check for keyw ord if (KeyW ordFound(line, keyW ord)) continue; // end check for keyw ord // begin Display D isplay(line); // end Display } //end } Richard Peschke | Coding Guidelines | | Page 63 Every Program in a Nutshell >Responsibility Handlers > One can combine this them > One must not blend them! . Int / double / vector / > The inner structure is never visible for the smart_ptr / file_handler / outside world > Make sure that every part of your program is GUI_button / GUI_DrawPanel always recognizable as what it is >Data Container > There is no fourth type! >Day / Month / Year* / Processors: > finite state machine . Events / Hits / Tracks / . Begin / run / end Configurations > Processors can be chained together > >Tasks / Processors Processors can contain other processors >Load file / save file / . filter events / event listener Event Event Event File reader File writer A A B Filter Converter File Handler MH MH MH File Handler MH MH MH Richard Peschke | Coding Guidelines | | Page 64 * From the example at the beginning MH = memory handler Don’t write Hybrid Classes What you expect: What you get: Richard Peschke | Coding Guidelines | | Page 65 Error Handling >Tasks can go wrong! bool SendReceivePacket(...) { >Error handling is not about M utexLock m (...); Actual Code try { in EUDAQ writing try catch m .Lock(); } catch (...) { // sw allow it everywhere! } SendPacket(...); return ReceivePacket(...); >Error handling is about: } . Leaving the system in a defined state . Clean up your mess . Communicating errors . (user/ caller) Richard Peschke | Coding Guidelines | | Page 66 Return Values VS Exceptions Richard Peschke | Coding Guidelines | | Page 67 Richard Peschke | Coding Guidelines | | Page 68 Error Safe Code with Return Values Richard Peschke | Coding Guidelines | | Page 69 Error Safe Code with Exceptions e d o c spot the d a difference b ll ti S Richard Peschke | Coding Guidelines | | Page 70 RAII RAII Richard Peschke | Coding Guidelines | | Page 71 Richard Peschke | Coding Guidelines | | Page 72 GSL Richard Peschke | Coding Guidelines | | Page 73 C - Style Interfaces What could go wrong? Richard Peschke | Coding Guidelines | | Page 74 What do I mean by C – Style Interfaces? void func(int* vec, size_t lengthO fVec); >Pointer + length Interfaces >No visible connection void func1(size_t, int*, size_t, int*, size_t, int*, size_t, int*, between pointer and its size_t, int*, size_t, int*, size_t, int*, size_t, int*, size_t); length (besides the name) >Can easily become unmaintainable >Hard to read >Very hard to reason about Richard Peschke | Coding Guidelines | | Page 75 C - Style Interfaces Neil Macintosh Richard Peschke | Coding Guidelines | | Page 76 Annotating Variables to show Intention Ugly Ugly Ugly Ugly Pretty awesome Neil Macintosh Richard Peschke | Coding Guidelines | | Page 77 What is the problem? >Pointer & length have no connection void func(size_t, int*); >Can we not just use a class? class array_view { public: void fun(array_view ); array_view (size_t, int*); int* data(); size_t size(); private: size_t m _size; int* m _data; }; Richard Peschke | Coding Guidelines | | Page 78 Use Objects Which handle the Pointer and Length Neil Macintosh Richard Peschke | Coding Guidelines | | Page 79 The Caller Side Herb Sutter Richard Peschke | Coding Guidelines | | Page 80 Herb Sutter Richard Peschke | Coding Guidelines | | Page 81 Summary Obey: Document: >Single definition rule >On code level why you are doing . Avoid magic numbers . Avoid copy and paste something > Single responsibility rule >On library level how to use the . If it doesn't fit on one screen it does more then one thing. classes/functions Use: >Provide Examples > Modern code Think Data: . Less typing/easier to read > RAII (smart pointer/ vector) >How can you visualize your . Avoid RAW memory access. data? Avoid: . Control plots! >C-style … Anything >Separate between how you store data on disk and how you use it in code Richard Peschke | Coding Guidelines | | Page 82 Richard Peschke | Coding Guidelines | | Page 83 Memory Accessing elements of an array >What is the difference? >If you access elements in order the computer can guess what is the next element and load it before you access it >Your computer acts like it has 3 levels of cache of almost infinite size Richard Peschke | Coding Guidelines | | Page 84 Herb Sutter Memory Memory Memory Memory Memory Memory Memory Richard Peschke | Coding Guidelines | | Page 85 Herb Sutter How to understand code? Richard Peschke | Coding Guidelines | | Page 86 How to understand code? void Unknown_Function(int *a, int b) { int i, j, p, t; >What does this function if (b < 2) return; p = a[b / 2]; do? for (i = 0, j = n - 1;; i++, j--) { while (a[i] < p) >What are the input i++; while (p < a[j]) parameters? j--; if (i >= j) break; t = a[i]; a[i] = a[j]; a[j] = t; } Unknown_Function(a, i); Unknown_Function(a + i, b - i); } Richard Peschke | Coding Guidelines | | Page 87 Think Data! >What does the Function do? It’s a sort algorithm! >Is the sort stable? Yes Unknown Function Richard Peschke | Coding Guidelines | | Page 88 Working Provide Examples int main () { >What does this function do? int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}; int size_of_a = sizeof a / sizeof a[0]; >What are the parameters? Print(a, size_of_a); //a = 4, 65, 2, -31, 0, 99, 2, 83, 782, 1 Unknown_Function(a, size_of_a ); Print(a, size_of_a); // a = -31 0 1 2 2 4 65 83 99 782 return 0; } Richard Peschke | Coding Guidelines | | Page 89 Template Example: >Generic function >Works on all containers . If it doesn’t work on your favorite container, provide begin, end and getContent functions and it will work >No inheritance needed >Flexible Richard Peschke | Coding Guidelines | | Page 90 Use of ‘const’ in Functions Return Values char *Function1() You cast away the const-ness of your { return “Some text”;} return value Function1()[1]=’a’; runtime error Fix: const char *Function1() compile time error { return "Some text";} Don’t cast away the const-ness of your return type http://duramecho.com/ComputerInfor mation/WhyHowCppConst.html Richard Peschke | Coding Guidelines | | Page 91 Two types of classes Data Structures Objects >Are just storage containers >Don’t show internal structure >Keep variables together >Have tasks >Show internal structure >Provide function to get/set inner >Don’t provide function to status manipulate content >Preserve invariance >Global functions can manipulate . Resource handling content >Objects derive functionality from Easy to implement new functionality other objects Easy to implement new Objects Richard Peschke | Coding Guidelines | | Page 92 Two types of classes Data Structures Objects Richard Peschke | Coding Guidelines | | Page 93 Object Or Data Structure? >A getter function doesn’t make an Object! >If you have a getter function like this you have direct access to the data! Richard Peschke | SCT Upgrade | 20.11.2013 | Page 94 Objects and Invariance >In the Process the system is in a >Multi thread safe status where “amount” is missing >Error handling in the system. >If another process checks the status at the same time it gets a wrong answer >No data recovery if an error happens >Hybrid Class Richard Peschke | Coding Guidelines | | Page 95 CONST basic explanation What does it mean? >YOU can only read from this object >Somebody else might be able to change the value Where should you use it? >Everywhere as long as the compiler doesn’t complain Richard Peschke | Coding Guidelines | | Page 96 what does const do with variables? > const int * Constant2 . declares that Constant2 is a variable pointer to a constant integer and > int const * Constant2 . is an alternative syntax which does the same > int * const Constant3 . declares that Constant3 is constant pointer to a variable integer > int const * const Constant4 . declares that Constant4 is constant pointer to a constant integer. http://duramecho.com/ComputerInfor mation/WhyHowCppConst.html Richard Peschke | Coding Guidelines | | Page 97 Const and Function parameters Choose your favorite Function i) t & ) t in i ns t & (co in d f2 3( voi f i) id t vo (in f1 id vo Richard Peschke | Coding Guidelines | | Page 98 Const and Function parameters void f1(int i) void f2(const int &i) >you need a copy of “I” >You don’t need a copy “I” and and >You don’t want to change >You don’t want to change the input parameter the input parameter void f3(int &i) >You want to change the input parameter Richard Peschke | Coding Guidelines | | Page 99 How to program T h is i s no t p ro gr am m i ng Richard Peschke | Coding Guidelines | | Page 100 Types and why do we care >Now he can meet his Wife in time and space >Nothing can go wrong now Well never mind! But at least they met each other… Richard Peschke | Coding Guidelines | | Page 101