TDDI12: Operating Systems, Real-time and Concurrent programming History of C • Short Introduction to C/C++ • • C was developed in the early 1970’s by Dennis Ritchie at Bell Labs (-> UNIX) + Objective: structured but flexible programming language e.g. for writing device drivers or operating systems + Book 1978 by Brian W. Kernighan and Dennis M. Ritchie (”K&R-C”) ”ANSI-C” 1989 standard by ANSI (”C89”) + The C standard for many programmers (and compilers...) + Became the basis for standard C++ + Java borrowed much of its syntax + The GNU C compiler implemented a superset (”GNU-C”) ”ISO-C” 1999 standard by ISO, only minor changes (”C99”) Copyright Notice: The lecture notes are includes slides from Christoph Kessler lectures in TDDB72. These lecture notes should only be used for internal teaching purposes at the Linköping University. Andrzej Bednarski, IDA Linköpings universitet, 2006 TDDI12, A. Bednarski, IDA, Linköpings universitet History of C++ Data Types • Basic types int bool char float • • C++ developed in the early 1980’s by Bjarne Stroustroup at Bell Labs, starting from ”C with Classes” + OOP layer (classes, objects, inheritance, polymorphism) grafted on top of C + Includes ANSI-C (and thereby all its low-level features) + More complex than Java or C# + Caution: Similar syntax to Java but different semantics ANSI/ISO standardized C++ 1997 Standard Template Library (STL) + standardized set of generic abstract data types in C++ Short Modifiers unsigned int long int 64 bit signed integer 3.4 32 bit signed integer (on 32 architectures) boolean value (true or false) 8 bit signed character = one byte signed floating point number singed 16 bit 32 bit unsigned integer (>= 0) Composite data types + arrays + structs + unions Programmer can define new type names with typedef TDDI12, A. Bednarski, IDA, Linköpings universitet 3.5 Variable Declaration TDDI12, A. Bednarski, IDA, Linköpings universitet Constants and Enumeration Declaring int iCounter; Creates an integer bool bDiskFull = false; Initialize it to false char chKey = ’a’; Initialize with character a • The C way (preprocessor directive) + How: #define ARRAYSIZE 10 + When: e.g. static arrays int myArray[ARRAYSIZE]; • The C++ way + How: const int NEWARRAYSIZE = 10; • TDDI12, A. Bednarski, IDA, Linköpings universitet 3.6 3.7 + When: e.g. dynamic arrays int foo() { int* pLocalArray = new int[NEWARRAYSIZE]; } Enumeration enum { red = 2, blue = 4, green, yellow } color; color = green; // expanded by compiler to color = 5; TDDI12, A. Bednarski, IDA, Linköpings universitet 3.8 1 Basic Operators Comments Assignment: = ex: iSum = 0; iSum = iOld; Math: +, -, *, /, % ex: iSum = iOne + iTwo / iThree; Bit: & (and), | (or), ^ (xor) ex: iMask = iMask | 1 /* This is a longer Combined: Increment: Decrement: +=, -=, *= ... ex: iSum += 5; ++foo, foo++ ex: iOld = iNew++; --foo, foo-ex: iSame = --iOld; Comparison: ==, >, >=, <, <=, != ex: (1 == 1), (1 != 2) multiline comment */ // Now I increase the counter counter++; /* commented out badidea++; ... foo--; */ TDDI12, A. Bednarski, IDA, Linköpings universitet 3.9 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.10 Branching: if … else Branching: switch … case if ( condition ) { ... } else if ( condition ) { ... } else { ... } switch (iSelection) { case 0: iFoo = iBar + 8; break; case CONSTANT: case ANOTHER_CONSTANT: break; default: ASSERT(false); } Conditions: iNumber == 0 (iNumber >= 0) || (bTest == false) bFirstTest && bSecondTest ( (iOne == 1) && (iTwo != 2) ) || bNoTest) TDDI12, A. Bednarski, IDA, Linköpings universitet 3.11 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.12 Loops: for / while Functions For: for ( initialize ; loop-condition ; update ) {} ex: for (int i = 0; i < ITERATIONS; i++) { iSum = piArray[i]; } return-type FunctionName ( param-type param-name ... ) ex: int Square (int iNumber) { int iResult = iNumber * iNumber; return iResult; } for (i = MAX; i == 0; i--) iIterations += 1; void PrintToScreen (char* pchOutput, int iXPosition) int GetRandom() While: while ( loop-condition ) {} ex: while (!bDone) { ... } TDDI12, A. Bednarski, IDA, Linköpings universitet Calling a function: int iResult = Square(3); PrintToScreen(&chOutput, iXPos); iRandom = GetRandom(); 3.13 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.14 2 Common Organization of a C/C++ Program • A C/C++ program is a collection of C/C++ source files + Module files (extensions .c, .cc) containing implementations of functionality (similar .java) + Header files (.h, .hh) containing declarations of global variables, functions, #include’d from all module files that need to see them, using the C preprocessor (missing in Java) When a module file is compiled successfully, an object code file (object module, binary module) is created (.o, corresponds to Java .class files) An executable (program) is a single binary file (a.out) built by the linker by merging all needed object code files There must be exactly one function called main() • • • Common Organization of a C/C++ Program stdio.h glob.h xy.h #include #include #include preprocess abc.c mymain.c compile def.c compile abc.o compile mymain.o def.o libc.a link a.out (executable) TDDI12, A. Bednarski, IDA, Linköpings universitet 3.15 TDDI12, A. Bednarski, IDA, Linköpings universitet Common Organization of a C/C++ Program glob.h /*Comment: declaration of mymain.c abc.c #include ”glob.h” globally visible functions and variables: */ extern int incr( int ); • • • // definition of var. initval: int initval = 17; int counter; // locally def. // definition of func. incr: void main( void ) int incr( int k ) { Header files usually contain the class declarations. Module source files usually contain implementations (definitions) of class member functions In-line definition of member functions is possible, but no coupling between file names and class implementations is enforced – member functions may be defined anywhere, using the scope resolution operator :: class My_Counter { extern int initval; Note the difference: { Declarations announce signatures (names+types). return k+1; Definitions declare (if } not already done) AND allocate memory. Header files should never TDDI12, A. definitions! Bednarski, IDA, Linköpings universitet 3.17 contain int My_Counter::get ( void ) { return counter; counter = initval; int get ( void ); } printf(“new counter: %d”, incr( counter ) ); int incr( void ); My_Counter c; // definition private: } void main( void ) { c.set( 17 ); } }; TDDI12, A. Bednarski, IDA, Linköpings universitet x: }; // other methods defined in other files ... int counter; 3.18 Composite Data Types (2): Unions • struct My_IComplex { x.re x.im • struct My_IComplex x; // declaration typedef struct My_IComplex icplx; #include ”My_ClassDef.hh” public: void set ( int ); Composite Data Types (1): Structs int re, im; C run-time library is linked with the user code Differences for C++ #include <stdio.h> #include ”glob.h” 3.16 // introduces new type name icplx • Unions implement variant records: all attributes share the same storage (start at 0) Unions break type safety + can interpret same memory location with different types If handled with care, useful in low-level programming icplx y; union My_flexible_Complex { void main ( void ) { struct My_IComplex ic; x.re = 2; c: // integer complex (re, im) – see above float f; // floatingpoint value – overlaps with ic y.im = 3 * x.re; printf(”x needs %d bytes, an icplx needs %d bytes\n”, sizeof( x ), sizeof (icplx) ); c.ic.re, c.f c.ic.im } c; } c.ic.re = 1141123417; // Remark: the sizeof operator is evaluated at compile time. printf(”Float value interpreted from this memory address contents is %f\n”, c.f ); // writes 528.646057 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.21 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.22 3 Composite Data Types (3): Arrays • Declaration/definition: int a[20]; int b[] = { 3, 6, 8, 4, 3 }; icplx c[4]; float matrix [3] [4]; 3 6 Pointers 8 4 3 • Addressing: Location of element a[i] starts at: (address of a) + i * elsize where elsize is the element size in bytes • Use: a[3] = 1234567; a[21] = 345; // ??, there is no array bound checking in C c[1].re = c[2].im; • Dynamic arrays: see later • Arrays are just a different view of pointers TDDI12, A. Bednarski, IDA, Linköpings universitet 3.23 • Each data item of a program exist somewhere in memory + Hence, it has a (start) memory address. • A variable of type pointer_to_type_X may take as a value the memory address of a variable of type X int a; int *p; // defines just the pointer p, not its contents! p = 0x14a236f0; // initialize p • Dereferencing a pointer with the * operator: *p = 17; // writes 17 to whatever address contained in p • The address of a variable can be obtained by the & operator: p = &a; // now, p points to address of a • Use the NULL pointer (which is just an alias for address 0) to denote invalid addresses, end of lists etc. TDDI12, A. Bednarski, IDA, Linköpings universitet 3.24 Pointers and Structs Why do we need pointers in C? • • Defining recursive data structures (lists, trees ...) • Argument passing to functions + simulates reference parameters – missing in C (not C++) ̶ void foo ( int *p ) { *p = 17; } Call: foo ( &i ); • Arrays are pointers + Handle to access dynamically allocated arrays + A 2D array is an array of pointers to arrays: ̶ int m[3][4]; // m[2] is a pointer to start of third row of m ̶ hence, m is a pointer to a pointer to an int • For representing strings – missing in C as basic data type + char *s = ”hello”; // s points to char-array {’h’,’e’,’l’,’l’,’o’, 0 } • For dirty hacks (low-level manipulation of data) • struct My_IComplex { int re, im; } c, *p; p = &c; + p is a pointer to a struct p->re is shorthand for *(p + (offset of re) ) + Example: as p points to c, &(p->re) is the same as &(c.re) + Example: elem->next = NULL; p: 0xafb024 c: 0xafb024 c.re c.im TDDI12, A. Bednarski, IDA, Linköpings universitet 3.26 Storage Classes in C (1) • Automatic variables + Local variables and formal parameters of a function + Exist once per call + Visible only within that function (and function call) + Space allocated automatically on the function’s stack frame + Live only as long as the function executes int *foo ( void ) // function returning a pointer to an int. { int t = 3; // local variable return &t; // ?? t is deallocated on return from foo, // so its address should not make sense to the caller... } TDDI12, A. Bednarski, IDA, Linköpings universitet 3.28 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.27 Storage Classes in C (2) • Global variables + Declared and defined outside any function + Unless made globally visible by an extern declaration, visible only within this module (file scope) int x; // at top level – outside any function extern int y; // y seen from all modules; only declaration int y = 4; // only 1 definition of y for all modules seeing y • + Space allocated automatically when the program is loaded Static variables + static int counter; + Allocated once for this module (i.e., not on the stack) even if declared within a function! + Value will survive function return: next call sees it TDDI12, A. Bednarski, IDA, Linköpings universitet 3.29 4 Dynamic Allocation of Memory in C • • • malloc( N ) + allocates a block of N bytes on the heap + and returns a generic (void *) pointer to it; + this pointer can be type-casted to the expected pointer type + Example: icplx *p = (icplx *)malloc ( sizeof ( icplx )); free( p ) + deallocates heap memory block pointed to by p Class and Objects Overview • • Can be used e.g. for simulating dynamic arrays: + Recall: arrays are pointers + int *a = (int *) malloc ( k * sizeof( int ) ); a[3] = 17; TDDI12, A. Bednarski, IDA, Linköpings universitet 3.30 C++ Constructors and Destructors (1) class Counter { public: Counter(); //constructor has same name as the class Counter( int ); //another constructor: C++ is polymorphic ~Counter(); //destructor – Tilde class name. No parameters. private: int x; }; Counter a; // definition; calls the first constructor automatically Counter b(17); // calls the second constructor automatically // Global variables reside in module, cannot be destructed. Class: + A group of functions and variables, so called member functions and member variables + Created all at once by special constructor function, destroyed by destructor function + Internal data can be protected from other functions + Good abstraction Object: + An instance of a class + All objects of one class have the same functions and variables, but different data in the variables TDDI12, A. Bednarski, IDA, Linköpings universitet C++ Constructors and Destructors (2) Counter *func0 ( void ) { // Intention: function returning instance of Counter (”factory”) Counter a; // allocated on stack – an automatic variable return &a; // ?? Destructor called for a upon return, } // stack frame deallocated -> stale address in a Solution 1: Implicit copying on return: Counter func1 ( void ) { Counter a; // allocated on stack – an automatic variable return a; // Destructor called for a upon return, // but a is copied to the caller via return before that } Call: TDDI12, A. Bednarski, IDA, Linköpings universitet 3.36 C++ Constructors and Destructors (3) Counter *func0 ( void ) { // Intention: function returning instance of Counter (”factory”) Counter a; // allocated on stack – an automatic variable return &a; // ?? Destructor called for a upon return, // stack frame deallocated -> stale address in a } Solution 2: Allocate the object instead on the heap: Counter *func2 ( void ) { Counter *pa; pa = new Counter(); // new returns a pointer to the object return pa; } TDDI12, A. Bednarski, IDA, Linköpings universitet 3.38 3.33 Counter b = func1(); TDDI12, A. Bednarski, IDA, Linköpings universitet // copy return value to b 3.37 C++ Constructors and Destructors (4) • • C++ has no garbage collection. Explicit deallocation of heap-allocated objects to avoid memory leaks X a = * fn_allocating_and_returning_a_heap_object(); Y *b = fn_allocating_and_returning_a_heap_object(); Z *c = new Z(); ... (use a, b, c) delete &a; // as free(), but also calls destructor ~X() delete b; delete c; TDDI12, A. Bednarski, IDA, Linköpings universitet 3.39 5 Static Class Members C++ Assignment Semantics /* In Foo.h file */ class Foo { … static Lock myLock; … } • Lock Foo::myLock(“lock name”); 3.40 Compiling C and C++ Programs • Example: GNU C Compiler: gcc (Open Source) • One command calls preprocessor, compiler, assembler, linker • Single module: Compile and link (build executable): + gcc mymain.c executable: a.out + gcc -o myprog mymain.c rename executable + gcc -lstdc++ -o myprog mymain.c (for C++ source file) Multiple modules: Compile and link separately + gcc -c -o mymain.o mymain.c compiler only + gcc -c -o other.o other.c compiles other.c + gcc other.o mymain.o call the linker, -> a.out + gcc -lstdc++ other.o mymain.o (for C++ source files) make (e.g. GNU gmake) + automatizes building process for several modules • • • 13 28 • /* In Foo.cc file */ TDDI12, A. Bednarski, IDA, Linköpings universitet Assignment of objects in Java copies the object references: Counter a; Counter b = a; • • Assignment of objects in C++ copies the object attributes: Counter a; Counter b = a; (hence, &b != &a) 13 13 Java objects are like C-pointers to (heap-allocated) structs. C++ objects are like C-structs. TDDI12, A. Bednarski, IDA, Linköpings universitet 3.41 C / C++: There is much more to say... • • • • • • • • • • • • • • Type conversions and casting Bit-level operations Operator precedence order Pointers to functions Variadic functions (with a variable number of arguments, e.g. printf() ) C standard library C preprocessor macros I/O in C and C++ C++ reference parameters C++ operator overloading C++ multiple implementation inheritance C++ exceptions C++ generic types (templates) STL ... Check the man pages TDDI12, A. Bednarski, IDA, Linköpings universitet 3.42 TDDI12, A. Bednarski, IDA, Linköpings universitet 3.43 Standard Template Library (STL) • • • http://www.sgi.com/tech/stl Introduction to STL Programmer’s Guide TDDI12, A. Bednarski, IDA, Linköpings universitet 3.44 6