0% found this document useful (0 votes)
4 views

SystemC-n-BehaviorCoding_Fall2021_Section3_C++

Uploaded by

Hua-Chien Chang
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

SystemC-n-BehaviorCoding_Fall2021_Section3_C++

Uploaded by

Hua-Chien Chang
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 74

+

SystemC, Behavior Coding


and Modeling
蘇培陞 博士
Alan P. Su, Ph.D.
[email protected], [email protected]
+
2

Drag picture to plac

Section 3
C++, The Object Oriented C
3-1 Introduction and Basics

Drag picture to plac


+ 3

C++
 The object oriented C
 Class
 Data members
 Access methods a.k.a member functions
 Inheritance
 Template
 Virtual function

 An object is an instance of a class

 Inheritance, a way to derive classes with common properties


from one base class
 Template, an abstraction that can be used to implement
different classes with different data types
 Virtual function, the way to derive differently on one function
name
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Object Oriented

4
+ 5

Object

 Object oriented is to mimic objects in the real world.


For example, a chair:
 Has parts like seat, back, armrest, legs, etc., i.e. data
members
 Has operations like sit, empty, move, lift, etc., i.e. member
functions
 Other examples:
 Table – table top, legs; move, lift, placed upon, remove
from
 FFT, IIR, FIR, H.264, etc. – data structure, algorithm
+ 6

Controlling assert()

 assert() is disabled if, before including assert.h, a macro


NDEBUG is defined. Then all the assert() statements in the
scope are eliminated by the pre-processor
#define NDEBUG
#include <assert.h>
 A common practice is to define another macro debug with its
value set to 0 or 1 to determine should NDEBUG be defined
#define debug 1 // 1: with assert
// 0: no assert
#if !debug
#define NDEBUG
#endif
#include <assert.h>
+ 7

Constructor
 Creates the instance and construct it
 Function name is the class name, no return type
specifying needed, since the return must be the
class itself
 Default constructor has no any input parameters.
It is by default called when a class is ‘instantiated’
 Can have multiple constructors, with different
input parameters for different usage. The compiler
will resolve which constructor to use by matching
exact input parameters and types
 No return statement
+ 8

Constructor Examples
// default constructor is not a must, but for the sake of
// coding discipline, it is best to code it anyway
List::List() {
_Length = 0;
_Array = NULL;
}

List::List(unsigned int num) {


_Length = num;
if (_Length == 0)
_Array = NULL;
else {
_Array = new int [_Length];
assert(_Array != NULL);
}
}

int main(int argc, char *argv[]) {


List dlist; // calls the default constructor
List clist(24); // calls the other one
}
+ 9

Copy Constructor

 Needed when
 a class object is passed to a function via a value parameter;
 a function returns a class object as its return value; and
 the result of a sub-expression is a class object that must be
held temporarily, until the result of another sub-expression
has been computed

 In each of these situations, the compiler must construct


a copy of the class object. To do so it uses a special
constructor function called the copy constructor
+ 10

Copy Constructor – An Example

// Copy constructor
List::List(const List& org) {
_Length = org._Length;
if (_Length > 0) {
_Array = new int [_Length];
assert(_Array != 0);
for (int i = 0; i < _Length; i++)
_Array[i] = org._Array[i];
}
else
_Array = NULL;
}
+ 11

Assignment Operator

 It is common to develop an assignment operator for a


class, so that we can use the simple = assignment to
copy the content of an object to another
 If you want to conveniently use = operator, then
assignment operator must be implemented. The
compiler cannot create one for you
 Assignment operator and copy constructor look very
much alike. However, assignment operator does not
instantiate an object. And it must has a return *this;
statement
+ 12

Assignment Operator Example

// Assignment operator
List& List::operator=(const List& org) {
if (this != &org) { // if the same one, do nothing
delete [] _Array; // _Array may not be NULL
_Length = org._Length;
if (_Length > 0) {
_Array = new int [_Length];
assert(_Array != 0);
for (int i = 0; i < _Length; i++)
_Array[i] = org._Array[i];
}
else
_Array = NULL;
}

return *this; // return this object


}
+ 13

Deconstructor

 Clear out an instance then destroy it


 Functionname is the class name with a
leading ~, no return type specification
 Canhave only one deconstructor, and
cannot have any input parameters
 Thecompiler always creates a default
deconstructor if not programmed
 No return statement
+ 14

Deconstructor – An Example

// deconstructor
List::~List() {
if (_Length != 0) {
delete [] _Array;
_Array = NULL;
_Length = 0;
}
}
+ 15

Member Function

 A member function is a function inside the class. And in


the implementation, we use a resolution operator, ::, to
specify which class a member function belongs to

// declaration in List.h
int setElement(unsigned int, int);

// implementation in List.cpp
int List::setElement(unsigned int pos,
int val) {
if (pos < _Size)
return _Array[pos];
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Namespaces

1
6
+ 17

namespace

 A namespace groups entities like classes, variables and


functions under a name
 The global space can then be divided into “sub-spaces,”
each on with its own name
 Format

namespace identifier {

entities

}
 where identifier is any valid identifier, and entities are
classes, variables and functions in the namespace
+ 18

namespace Example 1:
Resolution
#include <iostream>  Result
// std is a namespace too 5
using namespace std; 3.14159

namespace first {
int var = 5;
}

namespace second {
double var = 3.14159;
}

int main () {
cout << first::var << endl;
cout << second::var << endl;
return 0;
}
+ 19

namespace Example 2: using


#include <iostream>
using namespace std;
 Result
3
namespace first { 1.83729
int x = 3;
int y = 7; 7
} 3.14159
namespace second {
double x = 3.14159;
double y = 1.83729;
}

int main () {
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return 0;
}
+ 20

namespace Example 3: using


#include <iostream>  Result
using namespace std;
3
namespace first { 7
int x = 3;
3.14158
int y = 7;
} 1.83729

namespace second {
double x = 3.14159;
double y = 1.83729;
}

int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

I/O Stream

2
1
+ 22

std Namespace

#include <iostream>
#include <fstream>

using namespace std; // need to have this


// statement to not
// use the resolution
// operator, ::
+ 23

Basic Operators
 << - output operator
 >> - input operator
 endl – new line, “\n”

Examples
cout << “Got to run!” << endl;
cin >> inStr;
+ 24

<iostream>, Standard I/O


#include <iostream>
 cin – input stream function
int inInt;
cin >> inInt;
// scanf(“%d”, &inInt);
 cout – output stream function
cout << “Hello World!” << endl;
// printf(“Hello World\n”);
 cerr – error output stream function
cerr << “Error condition\n”;
 clog – log output stream function
clog << “Captain’s log” << endl;
+ 25

<fstream>, File Functions


 open(filename, ios::mode)
 mode: in, out, app
 eof()
 close()
 fail()

Example
fstream oFile, iFile;
int inInt;

iFile.open(“input”, ios::in);
oFile.open(“output”, ios::app);
if (!iFile.fail())
while(!iFile.eof()) {
iFile >> inInt;
oFile << inInt << endl;
}
oFile.close();
iFile.close()
}
+ 26

Output Formatting

 Manipulators
 setw(width) – display the next value in a field with the
specified width (1 is default)
 setprecision(precision) – display values with the
specified precision (6 is common default)
 setiosflags(flagList) – set the formatting flags, where
flagList is a sequence of one or more flags, separated
with the | operator, where flags are
 ios::showpoint – display decimal point and trailing 0’s
 ios::fixed – display real values in fixed-point
 ios::scientific – display real values in floating-point
 ios::left – display values left-justified within a field
 ios:right – display values right-justified within a field
+ 27

Formatted Output Examples


double Alpha = 8.0/3.0, Beta = 9.0/3.0;
cout << “\n(” << Alpha << “)”
<< “\n(“ << Beta << “)\n”;
cout << setiosflags(ios::showpoint|ios::fixed)
<< “\n(” << Alpha << “)”
<< “\n(“ << Beta << “)\n”;
cout << setiosflags(ios::showpoint|ios::fixed)
<< setprecision(3)
<< “\n(” << Alpha << “)”
<< “\n(“ << setw(10) << Beta << “)\n”;

Output is:
(2.666667)
(3)
(2.66667)
(3.00000)
(2.667)
( 3.000)
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Operator
Overloading

2
8
+ 29

Assignment Operator

 Assignment operator is one of the operator


overloadings
Its return type can either referenced or not, i.e. & or no
&
List& operator=(const List&);

List& List::operator=(const List &list)


{
statements

return *this;
}
+ 30

operator+ Overloading
 + is a binary operator. However its operation is to evaluate, then
the class returned is used to update. This is a member function of
the class, so class resolution is needed
 Its return type cannot be a reference, i.e. &

// member function declaration


List operator+(const List&);

// implementation
List List::operator+(const List &other) {
unsigned int loop =
_Size < other._Size ? _Size:other._Size;
// create a return object is required
List lt(loop);
for (int i = 0; i < loop; i++) {
lt._Array[i] = _Array[i] + other._Array[i];

return lt;
}
+ 31

operator+= Overloading
 += is a unary operator. However its operation is to evaluate, then the
class returned is used to update. This is a member function of the
class, so class resolution is needed
 Its return type can either referenced or not, i.e. & or no &

// member function declaration


List operator+=(const List&);

// implementation
List List::operator+=(const List &other) {
unsigned int loop =
_Size < other._Size ?
_Size:other._Size;
for (int i = 0; i < loop; i++) {
_Array[i] += other._Array[i];

return *this;
}
+ 32

operator++() Overloading
++ is a unary operator. However there are two forms of this
operator, prefix and postfix. operator++(), or operator++
(void), are used for prefix, e.g. ++list
Its return type can either referenced or not, i.e. & or no &

// member function declaration, prefix


List operator++();

// implementation
List List::operator++() {
for (int i = 0; i < _Size; i++) {
++_Array[i]; // prefix ++

return *this;
}
+ 33

operator++(int) Overloading

operator++(int) is used for postfix, e.g. list++. This int is not


used in the code. Its sole purpose is for the compiler to recognize
this is a postfix ++
Its return type can either referenced or not, i.e. & or no &

// member function declaration, postfix


List operator++(int);

// implementation
List List::operator++(int) {
List tmp(*this); // Retain a copy first
for (int i = 0; i < _Size; i++) {
_Array[i]++; // postfix++

return tmp;
}
+ 34

operator<< Overloading

<<,the output operator, can be overloaded as in the following


example. Note that it is a friend class to ostream so no class
resolution, ::, needed

// friend member function declaration


friend ostream& operator<<(ostream &, List);

// implementation
ostream& operator<<(ostream &out, List list) {
for (int i = 0; i < list._Size; i++)
out << list._Array[i] << “ “;
out << endl;
return out;
}
+ 35

operator>> Overloading
>>,the input operator, can be overloaded as in the following
example. Note that it is a friend class to istream so no class
resolution, ::, needed

// friend member function declaration


friend istream& operator>>(istream &, List&);

// implementation
istream& operator>>(istream &in, List &list)
{
for (int i = 0; i < list._Size; i++)
in >> list._Array[i];
return in;
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Inheritance

3
6
+
What is Inheritance?
 Take the chair for example. There are many different types
of chairs: arm chair, wheel chair, bench, stool, etc.
 But they all have two elements: seat and leg(s), and one
function: sit
 So we can have a base chair/class with above data member
and member function, then derive all different types of
chairs/classes. This derivation, is thus the property of
inheritance

3
7
+ 38

Encapsulation
 The purpose is to control who can do what, with following three
keywords:
 public
 Accessible inside and outside of this class
 Usually we make member functions public
 But you can make private functions as well

 private
 Accessible inside of this class only
 Usually we make data members private

 protected
 Accessible by this class, its friend classes, and derived classes

 Using private/protected restrict other programmers from


using these variables and/or functions. The purpose is more in
the engineering reasons than security reasons
+ 39

Base Class
Abase class holds the common properties (data member and
member functions)

class Employee {
private:
string name;
string id;
double net_pay;
public:
Employee();
Employee(string _name, string _id);
string get_name();
string get_id();
double get_net_pay();
void set_name(string _name);
void set_id(string _id);
void set_net_pay(double _net_pay);
void print_check();
};
+ 40

Base Class Implementation - I


#include <string>
#include <cstdlib>
#include <iostream>
#include "Employee.h"
using namespace std;

Employee::Employee() : name(""), id(""), netPay(0) {


// deliberately empty
}

Employee::Employee(string _name, string _id)


: name(_name), id(_id), netPay(0) {
// deliberately empty
}

string Employee::get_name() {
return name;
}

string Employee::get_id() {
return id;
}

double Employee::get_netPay() {
return netPay;
}
+ 41

Base Class Implementation - II


void Employee::set_name(string _name) {
name = _name;
}

void Employee::set_id(string _id) {


id = _id;
}

void Employee::set_netPay(double _netPay) {


netPay = _netPay;
}

void Employee::print_check() {
cout << "\nError: print_check function called for"
<< " a undefferentiated employee.\n"
<< " Program aborted\n";
exit(1);
}
+ 42

Derived Class I
And a derived class extends properties of the base
class
#ifndef HOURLYEMPLOYEE
#define HOURLYEMPLOYEE

#include <string>
#include "Employee.h“
using namespace std;

class HourlyEmployee : public Employee {


private:
double wageRate;
double hours;
public:
HourlyEmployee();
HourlyEmployee(string _name, string _id,
double _wageRate, double _hours);
void set_wageRate(double _wageRate);
void set_hours(double _hours);
double get_wageRate();
double get_hours();
void print_check();
};

#endif
+ 43

Derived Class I Implementation I


#include <string>
#include <iostream>
#include "HourlyEmployee.h"
using namespace std;

HourlyEmployee::HourlyEmployee() : Employee(), wageRate(0), hours(0) {


// deliberately empty
}

HourlyEmployee::HourlyEmployee(string _name, string _id,


double _wageRate, double _hours)
: Employee(_name, _id), wageRate(_wageRate), hours(_hours) {
// deliberately empty
}

void HourlyEmployee::set_wageRate(double _wageRate) {


wageRate = _wageRate;
}

void HourlyEmployee::set_hours(double _hours) {


hours = _hours;
}
+ 44

Derived Class I Implementation II


double HourlyEmployee::get_wageRate() {
return wageRate;
}

double HourlyEmployee::get_hours() {
return hours;
}

void HourlyEmployee::print_check() {
set_netPay(hours * wageRate);

cout << "\n_________________________________________\n";


cout << "Pay to the order of " << get_name() << endl;
cout << "The sum of " << get_netPay() << " Dollars\n";
cout << "\n_________________________________________\n";
cout << "Check Stub: NOT NEGOTIATABLE\n";
cout << "Employee Number: " << get_id() << endl;
cout << "Hourly Employee. \nHours worked: " << hours
<< " Rate: " << wageRate << " Pay: " << get_netPay() <<
endl;
}
+ 45

Derived Class II
#ifndef SALARIEDEMPLOYEE
#define SALARIEDEMPLOYEE

#include <string>
#include "Employee.h"

using namespace std;

class SalariedEmployee : public Employee {


private:
double salary;

public:
SalariedEmployee();
SalariedEmployee(string _name, string _id,
double _salary);
void set_salary(double _salary);
double get_salary();
void print_check();
};

#endif
+ 46

Derived Class II Implementation I


#include <string>
#include <iostream>
#include "SalariedEmployee.h"
using namespace std;

SalariedEmployee::SalariedEmployee() : Employee(), salary(0) {


// deliberately empty
}

SalariedEmployee::SalariedEmployee(string _name, string _id,


double _salary)
: Employee(_name, _id), salary(_salary) {
// deliberately empty
}

void SalariedEmployee::set_salary(double _salary) {


salary = _salary;
}
+ 47

Derived Class II Implementation I

double SalariedEmployee::get_salary() {
return salary;
}

void SalariedEmployee::print_check() {
set_netPay(salary);

cout << "\n_________________________________________\n";


cout << "Pay to the order of " << get_name() << endl;
cout << "The sum of " << get_netPay() << " Dollars\n";
cout << "\n_________________________________________\n";
cout << "Check Stub: NOT NEGOTIATABLE\n";
cout << "Employee Number: " << get_id() << endl;
cout << "Salaried Employee. Pay: " << get_netPay() << endl;
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Template

Generic Access Methods for Applicable


Types

4
8
+
Why Template?

 Take array or link list for example


 The way how array and link list are used is the same for all sorts
of data types, e.g. int, char, string, double, float, class
objects, etc.
 Before template is available, we need to implement exactly the
same access methods for each data type. The code size is huge
and error prone
 Using a generic data type to implement all the access methods in
a header file, then in the instantiation we give the target data
type so the compiler can mask to different data types with the
same template
 Note: the template class definition and implementation has to be
in one .h file. It has to be included in full to work.

4
9
+ 50

Why Template? – An Example 1/2

A swapVal function for integer type

void swapVal(int &var1, int &var2) {


int tmp;

tmp = var1;
var1 = var2;
var2 = tmp;
}
+ 51

Why Template? – An Example 2/2

A swapVal function for char type

void swapVal(char &var1, char &var2) {


char tmp;

tmp = var1;
var1 = var2;
var2 = tmp;
}
+ 52

Simple Function Template

Use template<class T> as the keyword to specify the


following function/class is a template. Notice that T can
be other names

template<class T>
void swapVal(T &var1, T &var2) {
T tmp;

tmp = var1;
var1 = var2;
var2 = tmp;
}
+ 53

Using Template
#include <iostream>
#include "swapVal.h"

using namespace std;

int main(int argc, char *argv[]) {


// swap integers
int integer1 = 1, integer2 = 2;
swapVal(integer1, integer2);
cout << "Swapped integers values are,\n"
<< "\tinteger1 = " << integer1
<< ", integer2 = " << integer2 << endl << endl;
// swap characters
char character1 = 'A', character2 = 'B';
swapVal(character1, character2);
cout << "Swapped character values are,\n"
<< "\tcharacter1 = " << character1
<< ", character2 = " << character2 << endl;
return 0;
}
+ 54

Class Template Example 1/4

#include <iostream>
#include <cstdlib>

using namespace std;

template<class Tmplt> // a generic class name Tmplt is used


class Pair {
private:
Tmplt first;
Tmplt second;

public:
Pair();
Pair(Tmplt firstVal, Tmplt secondVal);
// intentionally use automatic de-constructor creation

void setElement(int pos, Tmplt val);


Tmplt getElement(int pos);
};
+ 55

Class Template Example 2/4


template<class T> // a generic class name T is used
Pair<T>::Pair(T firstVal, T secondVal) {
first = firstVal;
second = secondVal;
}

template<class T>
void Pair<T>::setElement(int pos, T val) {
if (pos == 0)
first = val;
else if (pos == 1)
second = val;
else {
cout << "Error: Illegal pair position\n";
exit(1);
}
}
+ 56

Class Template Example 3/4

template<class T>
T Pair<T>::getElement(int pos) {
if (pos == 0)
return first;
else if (pos == 1)
return second;
else {
cout << "Error: Illegal pair position\n";
exit(1);
}
}
+ 57

Class Template Example 4/4


#include "Pair.h"

int main(int argc, char *argv[]) {

Pair<int> intPair(3, 4);


cout << "Integer pair initialized as <" << intPair.getElement(0)
<< ", " << intPair.getElement(1) << ">\n";
intPair.setElement(0, 17);
intPair.setElement(1, 23);
cout << "Integer pair reassigned as <" << intPair.getElement(0)
<< ", " << intPair.getElement(1) << ">\n\n";

Pair<char> charPair('g', 'r');


cout << "Character pair initialized as <" << charPair.getElement(0)
<< ", " << charPair.getElement(1) << ">\n";
charPair.setElement(0, 'O');
charPair.setElement(1, 'K');
cout << "Character pair reassigned as <" << charPair.getElement(0)
<< ", " << charPair.getElement(1) << ">\n\n";

return 0;
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Virtual Function

Resolve The Access Method Dynamically

5
8
+ 59

Why Virtual Function?

 Imagine the implementation of different shapes: line,


square, triangle, circle, octagon, etc.
 Base class is shape. And line, square, triangle, circle,
octagon etc. are classes derived from shape. Then a
draw() function is implemented for each shape derived
class
 Then, imagine all different shape is to be put into an array
or a list to be processed and drawn in a loop. We want to
simplify the coding and use one same function name
draw() in the loop
 Then the compiler makes the code dynamically resolve at
run time which draw() function to use
+ 60

An Example – Animals 1/7

#ifndef ANIMAL
#define ANIMAL
#include <string>

using namespace std;

class Animal {
private:
string kind;

public:
Animal();
Animal(string _kind);
string getKind();
virtual void say();
};
#endif
+ 61

An Example – Animals 2/7


#include <iostream>
#include “Animal.h”

Animal::Animal() {
kind = "";
}

Animal::Animal(string _kind) {
kind = _kind;
}

string Animal::getKind() {
return kind;
}

void Animal::say() {
cout << "Not any known animal, say nothing\n";
return;
}
+ 62

An Example – Animals 3/7


#ifndef DOG
#define DOG

#include "Animal.h"

class Dog : public Animal {


public:
Dog();
Dog(string _kind);
virtual void say();
};
#endif
+ 63

An Example – Animals 4/7


#include <iostream>
#include "Dog.h"

using namespace std;

Dog::Dog() : Animal("Dog") {
}

Dog::Dog(string _kind) : Animal(_kind) {


}

void Dog::say() {
cout << getKind() << " barks\n";
return;
}
+ 64

An Example – Animals 5/7

#ifndef WOLF
#define WOLF
#include “Dog.h"

class Wolf : public Dog {


public:
Wolf();
Wolf(string _kind);
virtual void say();
};
#endif
+ 65

An Example – Animals 6/7


#include <iostream>
#include “Wolf.h"

using namespace std;

Wolf::Wolf() : Dog(“Wolf") {
}

Wolf::Wolf(string _kind) : Dog(_kind) {


}

void Wolf::say() {
cout << getKind() << " woos\n";
return;
}
+ 66

An Example – Animals 6/7


#include <iostream>
#include “Wolf.h"

using namespace std;

Wolf::Wolf() : Dog(“Wolf") {
}

Wolf::Wolf(string _kind) : Dog(_kind) {


}

void Wolf::say() {
cout << getKind() << " woos\n";
return;
}
+ 67

An Example – Animals 7/7


#include <iostream>
#include "Animal.h"
#include "Dog.h"
#include "Wolf.h"

using namespace std;

int main(int argc, char *argv[]) {


Animal a;
Dog d;
Wolf w;

a.say(); // resolves to Animal::say(), error msg


d.say(); // resolves to Dog::say(), Dog barks
w.say(); // resolves to Wolf::say(), Wolf woos

return 0;
}
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

make

System Build Helper

6
8
+ 69

What Is make?

 A scripting language that can describe the dependency


between files, for example executable and object file,
then object file and source file. Then to execute the
given command, g++ for example, depends on the time
stamp difference.
 Say, the source file has a later time stamp than its
object or executable files, then the compilation will
execute. Otherwise do nothing when the source file is
older than the object or executable files, meaning after
last compilation the source file has not been modified
+ 70

Example
 Take the Animal classes as and example, we need to compile Animal.cpp,
Dog.cpp, Wolf.cpp and main.cpp then link into an executable

CC = g++
SRC = Animal.cpp Dog.cpp Wolf.cpp
OBJ = ${SRC:.cpp=.o} main.o
TARGET = animal

all: $(TARGET)
Tab Animal.o: Animal.h Animal.cpp
$(CC) -c Animal.cpp
Dog.o: Dog.h Dog.cpp
$(CC) -c Dog.cpp
Wolf.o: Wolf.h Wolf.cpp
$(CC) -c Wolf.cpp
main.o: main.cpp
$(CC) -c main.cpp
$(TARGET): $(OBJ)
$(CC) $(OBJ) -o $@

clean:
rm *.o
rm $(TARGET)
+ 71

Assignment 3 makefile
CC = g++
PCFLAG = -O1 -Wall -c
POFLAG = -O1 -Wall
HDR = Array.h List.h
SRC = ${HDR:.h=.cpp} main.cpp
OBJ = ${HDR:.h=.o} main.o
TARGET = list

all: $(TARGET)
Array.o: Array.h Array.cpp
$(CC) $(PCFLAG) $(@:.o=.cpp)
List.o: List.h List.cpp
$(CC) $(PCFLAG) $(@:.o=.cpp)
main.o: main.cpp
$(CC) $(PCFLAG) $(@:.o=.cpp)
$(TARGET): $(OBJ)
$(CC) $(POFLAG) $(LIB) $(OBJ) -o $@

clean:
rm $(OBJ)
rm $(TARGET)
+
Drag picture to placeholder or click ico

Not “English as
Second Language”
Drag picture to plac

Debug with Core


dump
System Build Helper

7
2
+
Core Dump & gdb

 Above is what looks like when you get a core dump


along with a segmentation fault. The core dump is
stored in the file looks like core.6273 as above. The
number is a sequence number given by the system.
 At this, first add –g to the compilation command,
recompile then run again to get another core dump.
Then, use gdb to debug like below
+3rd Section
To Be Continued…
Thanks to you all!

74

You might also like