Abuse of try and catch in exception handling

I have seen in some real life code that people sometimes use C++ for their convinience. Rather than solving the problem using powerful C++ features, they take dodgy shortcuts. Here is an example of peice of code that shows this abuse with 2 possible solutions.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This example shows how some people abuse throw and catch

#include<iostream>
using namespace std;
//
//The following interface is defined and being used by many classes
void function1();
//Now some programmer wants to change this to
//int function1();
//But this is not possible since overloading does not work for return types
//
//The same problem could instead be solved by other approach as follows:
void function1(int &abc);
int
function1(int dummy1, int dummy2); /*Note 2 dummy to avoid ambiguity with
the first overload. If the above overloaded func was not
there then only 1 dummy is sufficient
*/


int
main()
{

try

{

function1();
}

catch
(int xyz)
{

cout<<"\n\n";
cout<<"The function1() returned "<<xyz<<endl;
cout<<"\n\n";
}


int
first;
function1(first);
cout<<"The 1st overloaded function1() returned "<<first<<endl;
cout<<"\n\n";

cout<<"The 2nd overloaded function1() returned "<<function1(3,4)<<endl;
cout<<"\n\n";

return
0;
}


void
function1()
{

//function logic
throw 100;
}


//Overloaded function1()
void function1(int &abc)
{

abc = 120;
}


//Overloaded function1()
int function1(int dummy1, int dummy2)
{

return
140;
}





The output is as follows:

Using Const Cast

The following is an example to use the const_cast in C++.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example shows how to use const_cast
#include<iostream>

using namespace
std;

void
func1(int *x)
{

cout<<"\n2. xyz = "<<*x<<endl;

//Possible but its like cheating
(*x)++;
}



void
func2(const int *x)
{

cout<<"\n4. xyz = "<<*x<<endl;
//(*x)++; //Not possible to do this, compile time error
}

int
main()
{

int
xyz = 22;
const
int *abc = &xyz;
cout<<"\n1. xyz = "<<xyz<<endl;
//func1(abc); //Not possible to call, need a cast, compile time error
//Use const_cast only when you trust a function to not change the value
func1(const_cast<int *>(abc)); //Cast the constness of abc away
cout<<"\n3. xyz = "<<xyz<<endl;
func2(abc);
cout<<"\n5. xyz = "<<xyz<<endl;
}



The output of the program is as follows:

Example showing Pass by Value and Pass by Reference

This is a very simple example of Pass by value and pass by reference. I have shown both the simple type and structures in the same example.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example showing pass by value and pass by reference

#include<iostream>

using namespace
std;

//Pass by value
void func1(int num)
{

num++;
}


//Pass by reference
void func2(int &num)
{

num++;
}


typedef struct
x
{

int
a;
int
*b;
}
X ;

//Pass by value, pointer still incremented in b
void newFunc1(X xyz)
{

xyz.a++;
(*
xyz.b)++;
}


//Pass by reference, both variables incremented
void newFunc2(X &xyz)
{

xyz.a++;
(*
xyz.b)++;
}


int
main()
{

int
someNum = 3;
cout<<"\n1. someNum = "<<someNum<<endl;
func1(someNum);
cout<<"\n2. someNum = "<<someNum<<endl;
func2(someNum);
cout<<"\n3. someNum = "<<someNum<<endl;

cout<<"\n\nTrying this on structures"<<endl;
X someX;
someX.a = 13;
int
number = 50;
someX.b = &number;
cout<<"\n1. someX.a = "<<someX.a<<" someX.b = "<<*someX.b<<endl;
newFunc1(someX);
cout<<"\n2. someX.a = "<<someX.a<<" someX.b = "<<*someX.b<<endl;
newFunc2(someX);
cout<<"\n3. someX.a = "<<someX.a<<" someX.b = "<<*someX.b<<endl;
cout<<endl;
return
0;
}




The output is as follows:

Good and Bad Public Cloud candidates

I recently have a good conversation with Ed and Dean of RightScale on what are the characteristics making an application a good public cloud citizen.

Good Public Cloud Candidates

Being stateless
  • There is no warm up and cool down periods required. Newly started instances are immediately ready to work
  • Work dispatching is very simple when any instances can do the work
Compute intensive with small dataset size
  • Cloud computing enable quick deployment of a lot of CPU to work on you problem. But if it requires to load large amount of data before the CPU can start their computation, the latency and bandwidth cost will be increased
Contains only non-sensitive data
  • Although cryptography technology is sufficient to protect your data, you don't want to pay the CPU overhead for encrypt/decrypt for every piece of data that you use in the cloud.
Highly fluctuating workload pattern
  • Now you don't need to provision inhouse equipment to cater for the peak load, which sits idle for most of the time.
  • The "pay as you go" model save cost because you don't pay when you are not using them
New application launch with unknown workload anticipation
  • You don't need to take the risk of over-estimating the popularity of your new application, and buy more equipment than you actually need.
  • You don't need to take the risk of under-estimating the popularity and ends up frustrating your customer because you cannot handle their workload.
  • You can defer your big step investment and still be able to try out new ideas.


Bad Public Cloud Candidates

Demand special hardware
  • Most of the cloud equipment are cheap, general purpose commodities. If you application demands a certain piece of hardware (e.g. a graphic processor for rendering), it will just not work or awfully slow.
Demand multi-cast communication facilities
  • Most of the cloud providers disable multicast traffic in their network
Need to reside in a particular geographic location
  • If there is legal or business requirement demanding your server to run in a physical location and that location is not covered by cloud providers, then you are out of luck.
Contain large dataset
  • Bandwidth cost across cloud boundary is high. So you may endup have a large bill when loading large amount of data into the cloud
  • Loading large amount of data also takes time. You need to compare that with the overall time of the processing itself to see if it makes sense
Contain highly sensitive data
  • Legal, liabilities, auditing practices hasn't catched up yet. Companies running their core business app in the cloud will face a lot of legal challenges
Demand extremely low latency of user response
  • Since you have no control about the location of where the machines are residing, latency is usually increase when you run your app in the cloud residing in a remote location
Run by 24 x 7 with extremely stable and non-fluctuating workload pattern
  • If you are using a machine without shutting down, then many cost analysis report shows running the machine inhouse will be cheaper (especially for large enterprise who already have data center setup and a team of system administrators)

Hybrid Cloud


I personally believe the real usage pattern of public cloud for large enterprise is to move the fluctuating workload into the public cloud (e.g. Christmas sales for e-commerce site, Newly launched services) but retain most of the steady workload traffic in-house. In fact, I think enterprise is going to move in and out their application constantly based on the change of traffic patterns.

It is much appropriate to do the classification at the component level rather than at the App level. Instead of saying whether the App (as a whole) is suitable or not, we should determine which components of the app should run in the public cloud and which should stay in the data center.

In other words, an Application is running in a hybrid cloud mix, which span across public and private cloud.

The ability to move your application “frictionless” across cloud boundaries and manage the scattered components in a holistic way is key. Once you have this freedom to move, then the price of a particular public cloud provider has less impact on you because you can easily move to any cheaper provider at any time.

An example of using Typename with Templates

Typename is used with templates where the type is unknown. Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter. Only use the keyword typename in template declarations and definitions.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows an how to use typename with templates
//Example from
//http://www.deitel.com/articles/cplusplus_tutorials/20060428/index.html
#include<iostream>

//using namespace std; //No need to use the whole namespace std
using std::cout;
using
std::endl;

// function template printArray definition
template<typename T>
void
printArray( const T *array, int count )
{

for
( int i = 0; i < count; i++ )
{

cout << array[ i ] << " ";
}

cout << endl;
}
// end function template printArray

int
main()
{

const
int ACOUNT = 5; // size of array a
const int BCOUNT = 7; // size of array b
const int CCOUNT = 6; // size of array c

int
a[ ACOUNT ] = { 1, 2, 3, 4, 5 };
double
b[ BCOUNT ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
char
c[ CCOUNT ] = "HELLO"; // 6th position for null

cout << "Array a contains:" << endl;
// call integer function-template specialization
printArray( a, ACOUNT );

cout << "Array b contains:" << endl;
// call double function-template specialization
printArray( b, BCOUNT );

cout << "Array c contains:" << endl;
// call character function-template specialization
printArray( c, CCOUNT );

return
0;
}



Note in the above example you could have replaced 'typename' with 'class' and obtain the same results. Compare this with our basic template example discussed before.

The output of the program is as follows:

Functions, Methods and Operations

In C programming we had functions. In C++ we have functions, methods and operations. Here is what I understand the differences between them are:
  • Functions: These are the same old functions used in C programming case
  • Methods: OOPS concept used to refer a function inside a class. So if your C++ code has two functions where one of the function is part of a class and the other is directly within the code without being part of a class then the first one is a method and the other one a function.
  • Operations: I found operations being used generally in UML based books which may be talking about C++ or Java. As far as I understand, operations are abstract methods. When methods are declared (no implementation) then they are referred to as operations. This is the case when its UML representation like a class diagram or C++ code. When the implementation of that method is done (in C++ code) it i referred to as a method.

A simple example of C++ Exceptions

Exceptions is a very powerful mechanism by which errors can be handled within the programs in C++. In C if an exception occurs (for example overflow, underflow, memory allocation failure, etc) then the program would just crash. In C++ these problems can be handled by use of exceptions.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This example shows different ways of throwing and catching
//exceptions and handling of exceptions

#include<iostream>
//#include<exception> //May be required on other platforms

using namespace
std;

void
function1();
void
function2();
void
function3();
void
function4();

class
zgException: public exception
{

//overloading the what() method
virtual const char* what() const throw()
{

return
"zgException occured";
}
}
zgEx;


int
main()
{

function1();
function2();
function3();
function4();

return
0;
}


//Throwing an integer
void function1()
{

cout<<"\nfunction1()"<<endl;
try

{

throw
123;
}

catch
(int a)
{

cout<<"Exception caught with value "<<a<<endl;
}
}


//Throwing a string but no mechanism to catch it
void function2()
{

cout<<"\nfunction2()"<<endl;
string s = "function2() exception";
try

{

throw
s;
}

catch
(exception &e)
{

cout<<"Exception message: "<<e.what()<<endl;
}

catch
(...)
{

cout<<"All exceptions not handled are caught here"<<endl;
}
}


//Throwing a string and catching it
void function3()
{

cout<<"\nfunction3()"<<endl;
string s = "function3() exception";
try

{

throw
s;
}

catch
(exception &e)
{

cout<<"Exception message: "<<e.what()<<endl;
}

catch
(string &ss)
{

cout<<"Exception message: "<<ss.c_str()<<endl;
}

catch
(...)
{

cout<<"All exceptions not handled are caught here"<<endl;
}
}


//Throwing a class and catching it
void function4()
{

cout<<"\nfunction4()"<<endl;
string s = "function4() exception";
try

{

throw
zgEx;
}

catch
(exception &e)
{

cout<<"Exception message: "<<e.what()<<endl;
}

catch
(...)
{

cout<<"All exceptions not handled are caught here"<<endl;
}
}






The output is as follows:

A Word and Letter Counter program example

This is a very simple program but people can sometime get lost in writing them. I have not taken into account all the different error scenarios but this program is quite robust.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//In this program we will count the total number of words, letters
//and the frequency of each letter. For simplicity we will end the
//program when enter is pressed.
#include<iostream>

using namespace
std;

void
wordLetterCounter(int &numWords, int &numLetters, int letterCount[]);

int
main()
{

int
numWords = 0, numLetters = 0;
int
letterCount[26]={0}; //each letter count init to 0

cout<<"\n\nPlease enter some words and finish by pressing enter : ";

wordLetterCounter(numWords, numLetters, letterCount);

cout<<"\n\nNumber of Words = "<<numWords<<" Number of Letters = "<<numLetters<<endl;
cout<<"\nFrequency of letters as follows:"<<endl;
for
(int i = 0; i < 26; i++)
{

cout<<char('a'+i)<<" = "<<letterCount[i]<<endl;
}


return
0;
}


void
wordLetterCounter(int &numWords, int &numLetters, int letterCount[])
{

char
c;
char
lastLetter=' ';

//Remember 'A'=65, 'Z'=90 and 'a'=97, 'z'=122 in Ascii
while(cin.get(c))
{

//Converting upper to lower case to make it case insensitive
if(c >= 'A' && c <= 'Z')
c+=char(32);

//Increase Letter Count and number of letters
if(c >= 'a' && c <= 'z')
{

letterCount[c - 'a']++;
numLetters++;
}


//Increase number of words
if(c == ' ' && lastLetter != ' ')
numWords++;

//If new line then break;
if(c == '\n')
{

//Before you exit, the numWords should be increased if there was atleast 1 letter
if(numLetters)
numWords++;
break
;
}

lastLetter = c;
}
}




The Output is as follows. Note that there is a '.' and many spaces between Dr. and Spock but the wordcount is correct.

An example of C++ Multimap

The following is a simple example of C++ Multimap class.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program shows use of multi-maps
//We input multiple phone numbers for different people
#include<iostream>
#include<map>
#include <string>

using namespace
std;

//forward declaration
void printer(multimap<string, int> pN);

int
main()
{

multimap<string, int> phoneNums;

//Insert key, value as pairs
phoneNums.insert(pair<string, int>("Joe",123));
phoneNums.insert(pair<string, int>("Will",444));
printer(phoneNums);

//Insert duplicates
phoneNums.insert(pair<string, int>("Joe",369));
phoneNums.insert(pair<string, int>("Smith",567));
phoneNums.insert(pair<string, int>("Joe",888));
phoneNums.insert(pair<string, int>("Will",999));
printer(phoneNums);

//Checking frequency of different keys
cout<<"\n\nFrequency of different names"<<endl;
cout<<"Number of Phones for Joe = "<<phoneNums.count("Joe")<<endl;
cout<<"Number of Phones for Will = "<<phoneNums.count("Will")<<endl;
cout<<"Number of Phones for Smith = "<<phoneNums.count("Smith")<<endl;
cout<<"Number of Phones for Zahid = "<<phoneNums.count("Zahid")<<endl;

//Print all Joe from the list and then erase them
pair<multimap<string,int>::iterator, multimap<string,int>::iterator> ii;
multimap<string, int>::iterator it; //Iterator to be used along with ii
ii = phoneNums.equal_range("Joe"); //We get the first and last entry in ii;
cout<<"\n\nPrinting all Joe and then erasing them"<<endl;
for
(it = ii.first; it != ii.second; ++it)
{

cout<<"Key = "<<it->first<<" Value = "<<it->second<<endl;
}

phoneNums.erase(ii.first, ii.second);
printer(phoneNums);

return
0;
}


//This method prints the vector
void printer(multimap<string, int> pN)
{

cout<<"\n\nMultimap printer method"<<endl;
cout<<"Map size = "<<pN.size()<<endl;
multimap<string, int>::iterator it = pN.begin();
while
(it != pN.end())
{

cout<<"Key = "<<it->first<<" Value = "<<it->second<<endl;
it++;
}
}




The output is as follows:

Check out this stream