Reliable C++ development - session 1: From C to C++ (and some C++ features) Thibault CHOLEZ - thibault.cholez@loria.fr TELECOM Nancy - Université de Lorraine LORIA - INRIA Nancy Grand-Est From Nicolas Rougier s C++ crash course 22/09/2014
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 2 / 27
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 3 / 27
First words Goal of the class Hands-on C++! Learning similarities and differencies regarding C and JAVA Learning basic concepts and features of C++ Learning more advanced features used in embedded systems Structure of the class Five sessions of two hours (within the next three weeks) For each session : 30 min talk on C++ concepts, then short partical exercices on computer 4 / 27
First words Program From C to C++ : reminder C++ features and object programming Functionnalities for reliable programming Optimizations and performance Exam : few theoritical questions + pratical exercices on computer Environment Basic Linux OS and tools : g++, console, text editor No Integrated Development Environment (hides complexity) 5 / 27
Why a class on C++? C and C++ are still the most widely used programming languages For operating systems (SLOC in debian : 49% in C, 21% in C++) For general purpose software (SourceForge statistics : 18% of software in C++, 16% in C)... and also for embedded software (with an emphasis on real time or low ressource constraints)! 6 / 27
Pros Cons Why not JAVA for embedded software? Programmer friendly : features for reliability, garbage collector, etc. Portable write once, run anywhere : same byte-code works everywhere (not tied to hardware but to JVM, great advantage to deal with smartphones heterogeneity) JRE simulates hardware : slower execution (not as bad as it used to be thanks to just-in-time compilation but still) Waste of ressources (memory, CPU) Odd coupling with hardware : JRE as a stack machine while CPU is probably register-based (RISC) (that s why Dalvik was created) Unpredictability of JVM is an issue for real time system : you don t want the garbage collector to work during during a critical time 7 / 27
C / C++ Pros Cons C is the closest high-level language to the machine, C++ is just an improved version with object-oriented features Close to the hardware, efficient execution and low ressource usage (with proper code) No interference of VM to disturb execution Possibility to mix C++ with asm code Hard to write efficient and reliable code without strong knowledge and experience (that s why you are here) Specific compilation for each hardware architecture needed 8 / 27
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 9 / 27
Pre-processor Just like in C, very dumb text editing tool, still useful Features #define MACRO NAME value find and replace, (in C) good to define constant in UPPER CASE #include <header file> line replaced by whole content of the header file #ifdef macro_name /* Code to use if macro defined */ #else /* Code to use otherwise */ #endif #ifndef SOME_UNIQUE_NAME #define SOME_UNIQUE_NAME #endif 10 / 27
Compilation and Link edition Simplest way gcc -o binary source1.c source2.c source3.c Better way We want to approach modular programming for many reasons (separation of concerns, team work, maintenance) Source code organized in different meaningful files and folders, as autonomous as possible Do not recompile everything for a small change : recompile only the modified file(s) and redo the link edition The linker creates the exec file from multiple object files / librairies gcc -c source1.c gcc -o binary source1.o source2.o source3.o 11 / 27
Separate compilation and Makefile Makefile Simple automated tool dealing with file dependencies during separate compilation : target: dependencies commands additionnal rules are commonly used : all to generate the main executable, clean to remove object files, etc. also, additionnal variables are commonly used : CC for the compiler, CFLAGS for the compilation options LDFLAGS for the linker options, EXEC for the name of the executable file 12 / 27
CXX=g++ CXXFLAGS=-Wall LDFLAGS= EXEC=hello all: $(EXEC) Example of Makefile hello: hello.o main.o $(CXX) -o hello hello.o main.o $(LDFLAGS) hello.o: hello.c $(CXX) -o hello.o -c hello.c $(CXXFLAGS) main.o: main.c hello.h $(CXX) -o main.o -c main.c $(CXXFLAGS) clean: rm -rf *.o 13 / 27
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 14 / 27
Memory : stack vs heap The memory of each process is split in 3 big segment : Data (Code+Globals), Stack, Heap. Their place / size is constrained by the OS. The stack The stack stores temporary variables created by each function which pushes a temporary stack frame for its execution. The stack is a FILO (first in, last out) data structure, that is managed and optimized by the CPU (fast read and write to stack variables). Another advantage of using the stack to store variables : no need to allocate memory by hand, memory is automaticallt freed Limits : the stack has strong size limits, stack variables only exist while the function that created them is running 15 / 27
Memory : stack vs heap The heap Heap is the dynamic memory (manually managed by you) Variables can be accessed globally and no limit on memory size Memory may become fragmented and wasted (memory leaks) if not properly managed Try to gather mallocs and frees in specific parts of your code (initialization and stop phases) 16 / 27
Pointers Pointers are variable storing a memory address : Pointer value = rank of a memory cell. int *p declares a pointer variable p which is a pointer to an integer value *p is then the pointed value, interpreted according to the pointer type the & operator retrieves the adress of something 17 / 27
Memory management in C malloc and free to use the heap memory High level API to deal with chunks in heap There is only 3 functions to know : request a new memory chunk, return a memory chunk, expend a memory chunk #include <stdlib.h> void*malloc(int size) void free(void*p) void*realloc(void*p,int size) 18 / 27
New/Delete Memory management in C++ The new and delete keywords are used to allocate and free memory. They are object-aware so you d better use them instead of malloc and free (no more sizeof(struct toto)) Never cross the streams (new/free or malloc/delete) Delete does two things : it calls the destructor and it deallocates the memory. int *a = new int; delete a; int *b = new int[5]; delete [] b; 19 / 27
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 20 / 27
References A reference allows to declare an alias to another variable. As long as the aliased variable lives, you can use indifferently the variable or the alias. References are extremely useful when used with function arguments since it saves the cost of copying parameters into the stack when calling the function. int x; int& foo = x; foo = 42; std::cout << x << std::endl; 21 / 27
Namespaces Namespace allows to group classes, functions and variable under a common scope name that can be referenced elsewhere. There exists some standard namespace in the standard template library such as std. The example below should give values 3 and 5 : namespace first { int var = 5; } namespace second { int var = 3; } cout << first::var << endl << second::var << endl; 22 / 27
Default parameters You can specify default values for function parameters. When the function is called with fewer parameters, default values are used. Watch out, it can create ambiguity. The code below should obtain values 4, 5 and 6. float foo( float a=0, float b=1, float c=2 ) {return a+b+c;} cout << foo(1) << endl << foo(1,2) << endl << foo(1,2,3) << endl; 23 / 27
Overloading Function overloading refers to the possibility of creating multiple functions with the same name as long as they have different parameters (type and/or number). It is not legal to overload a function based on the return type! The code below should obtain values 4, 5 and 6. float add( float a, float b ) {return a+b;} int add( int a, int b ) {return a+b;} 24 / 27
Const and inline functions Defines and macros are bad if not used properly as illustrated below For constants, prefer the const notation (it adds type to the constant) #define SQUARE(x) x*x int result = SQUARE(3+3); const int two = 2; int inline square(int x) {return x*x;} 25 / 27
Plan 1 Introduction 2 Reminder on C compiler 3 Reminder on memory managment 4 Some features 5 Exercices 26 / 27
Up to you C++ Hello World #include<iostream> int main() { std::cout << "Hello, new world!\n"; } Compilation and execution g++ hello.cpp -o hello./hello 27 / 27