Download presentation
Presentation is loading. Please wait.
1
. Compilation / Pointers Debugging 101
2
Compilation in C/C++ hello.c Preprocessor Compiler stdio.h tmpXQ.i (C code) hello.o (object file)
3
Preprocesser A single-pass program that u Include header files u Expands macros u Control conditional compilation u Remove comments
4
#include directive #include ”foo.h” u Include the file “foo.h”, from current directory #include u Include the file “stdio.h” from the standard library directory (part of compiler installation)
5
Modules & Header files Complex.c struct Complex { double _real, _imag; }; Complex addComplex(Complex, Complex); Complex subComplex(Complex, Complex);... complex.h #include #include “complex.h” // implementation Complex addComplex(Complex a, Complex b) { … complex.c #include “complex.h” int main() { Complex c; … MyProg.c
6
Header files Header file contain u Definition of data types u Declarations of functions & constants That are shared by multiple modules. #include directive allows several modules to share the same set of definitions/declarations
7
#define directive #define FOO 1 … int x = FOO; is equivalent to … int x = 1;
8
#define with arguments #define square(x) x*x b = square(a); is the same as b = a*a;
9
#define -- cautions #define square(x) x*x b = square(a+1); c = square(a++); Is it what we intended? b = a+1*a+1; // b = 2*a+1; c = a++*a++; // c = a*a; a+=2;
10
#define #define directive should be used with caution Alternative to macros: u Constants enum { FOO = 1; }; or const int FOO = 1; u Functions – inline functions (C++, later on)
11
#if directive u Allows to have conditional compilation #if defined(DEBUG) // compiled only when DEBUG exists printf(“X = %d\n”, X); #endif
12
#if – header safety Complex.h: struct Complex { … MyStuff.h: #include “Complex.h” Main.c #include “MyStuff.h” #include “Complex.h” Error: Complex.h:1: redefinition of `struct Complex'
13
#if – header safety Complex.h (revised): #if !defined(COMPLEX_H) #define COMPLEX_H struct Complex { … #endif Main.c: #include “MyStuff.h” #include “Complex.h” // no error this time
14
Preprocessor We can test what the preprocessor does > gcc –E hello.c will print the C code after running preprocess
15
assert.h #include // Sqrt(x) - compute square root of x // Assumption: x non-negative double Sqrt(double x ) { assert( x >= 0 ); // aborts if x < 0 … If the program violates the condition, then assertion "x >= 0" failed: file "Sqrt.c", line 7 u The exception allows to catch the event in the debugger
16
assert.h Important coding practice u Declare implicit assumptions u Sanity checks in code u Check for violations during debugging/testing Can we avoid overhead in production code?
17
assert.h #undef assert // procedure that actually prints error message void _assert(char* file, int line, char* test); #ifdef NDEBUG #define assert(e) ((void)0) #else #define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e)) #endif
18
Compilation u Takes input C-code and produces machine code (object file) gcc –c Main.c Main.c Main.o u The object file does not contain all external references It leaves names, such as “printf”, “addComplex”, etc. as undefined references
19
Linking u Combines several object files into an executable file No unresolved references Main Preprocessor Compiler Complex.c Complex.o Main.c Main.o Linker libc.a
20
Link errors The following errors appear only at link time u Missing implementation > gcc -o Main Main.p Main.o(.text+0x2c):Main.c: undefined reference to `foo' u Duplicate implementation > gcc -o Main Main.o foo.o foo.o(.text+0x0):foo.c: multiple definition of `foo' Main.o(.text+0x38):Main.c: first defined here
21
Memory Arrangement u Memory is arrange in a sequence of addressable units (usually bytes) sizeof( ) return the number of units it takes to store a type. sizeof(char) = 1 sizeof(int) = 4 (on most of our machines)
22
Memory int main() { char c; int i,j; double x; … cijx
23
Arrays Defines a block of consecutive cells int main() { int i; int a[4]; … ia[0]a[1]a[2]a[3]
24
Arrays u C does not provide any run time checks int a[4]; a[-1] = 0; a[4] = 0; This will compile and run (no errors) …but can lead to unpredictable results. u It is the programmer’s responsibility to check whether the index is out of bounds…
25
Arrays u C does not provide array operations int a[4]; int b[4]; … a = b; // illegal if( a == b ) // illegal …
26
Array Initialization int arr[3] = {3, 4, 5}; // Good int arr[] = {3, 4, 5}; // Good - The same int arr[4] = {3, 4, 5}; // Good - The last is 0 int arr[2] = {3, 4, 5}; // Bad int arr[2][3] = {{2,5,7},{4,6,7}}; // Good int arr[2][3] = {2,5,7,4,6,7}; // Good - The same int arr[3][2] = {{2,5,7},{4,6,7}}; // Bad int arr[3]; arr = {2,5,7}; // Bad - array assignment only in initialization
27
Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; ijx 1
28
Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; ijx 1 0x0100
29
Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; ijx 1 0x0100 1
30
Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; ijx 1 0x0100 0x01041
31
Pointers int main() { int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3; ijx 1 0x0100 0x01043
32
Pointers u Declaration *p; p points to objects of type u Pointer value *p = x; y = *p; *p refers to the object p points to u value pointer &x - the pointer to x
33
Example – the swap function Does nothingWorks void swap(int a, int b) { int temp = a; a = b; b = temp; } …. int main() { int x, y; x = 3; y = 7; swap(x, y); // now x==3, y==7 …. void swap(int *pa, int *pb) { int temp = *pa; *pa = *pb; *pb = temp; } …. int main() { int x, y; x = 3; y = 7; swap(&x, &y); // x == 7, y == 3 …
34
Pointers & Arrays int *p; int a[4]; p = &a[0]; *(p+1) = 1; // assignment to a[1]! pa[1]a[2]a[3]a[0]
35
Pointers & arrays Arrays are essentially constant pointers int *p; int a[4]; p = a; // same as p = &a[0] p[1] = 102; // same as *(p+1)=102; *(a+1) = 102; // same p++; // p == a+1 == &a[1] a = p; // illegal a++; // illegal
36
Pointers & Arrays int foo( int *p ); and int foo( int a[] ); Are declaring the same interface u In both cases, a pointer to int is being passed to the function foo
37
Pointer Arithmetic int a[4]; int *p = a; char *q = (char *)a; // Explicit cast // p and q point to the same location p++; // increment p by 1 int (4 bytes) q++; // increment q by 1 char (1 byte) a[1]a[2]a[3]a[0] q p
38
Pointer arithmetic int FindFirstNonZero( int a[], int n ) { int *p; for( p = a; p < a+n && (*p) == 0; p++ ) ; return p-a; } Same as int FindFirstNonZero( int a[], int n ) { int i; for( i = 0; i < n && a[i] == 0; i++ ) ; return i; }
39
void * void *p defines a pointer to undetermined type int j; int *p = &j; void* q = p; // no cast needed p = (int*)q ; // cast is needed
40
NULL pointer u Special value: uninitialized pointer int *p = NULL; … if( p != NULL ) { … }
41
NULL pointer int *p = NULL; *p = 1; Will compile… … but will lead to runtime error
42
Debugging 101 1. “Define” the bug --- reproduce it 2. Use debugger 3. Don’t panic --- think! 4. Divide & Conquer
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.