Wednesday, 24 February 2010

The power of 'typedef' in C++

C++ allows the definition of our own types based on other existing data types. We can do this using the keyword typedef, whose format is:

typedef existing_type new_type_name ;

where existing_type is a C++ fundamental or compound type and new_type_name is the name for the new type we are defining.

For example:
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];

There are many scenarios where using typedef's are very advantageous. The following program is written based on the reasons for using typedef's as defined by Herb Sutter in his book "More Exceptional C++"



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program showing the advantages of using typedefs in C++

#include<iostream>
#include<map>
#include<vector>
#include<list>
#include<assert.h>

using namespace
std;

//Comment/Uncomment as required
//#define USING_MAPS
#define USING_OTHER_STL

//5 - Portability: Useful if different users want to use different STL classes
#if defined USING_MAPS
typedef map<int,int> table; //1 - Typeability: table is easier to type
#else
//4 - Flexibility: In future you could replace a map by a vector for example
typedef vector<int> table;
//typedef list<int> table;
#endif

typedef
table::iterator tableIter;

//map<int,int> multiplicationTableTill10(int num); - not very readable
table multiplicationTableTill10(int num); //2 - Readability: Easier to read

int
main()
{

int
i = 1;
table t = multiplicationTableTill10(7);
for
(tableIter t_iter = t.begin(); t_iter != t.end(); ++t_iter, ++i)
{

#if defined USING_MAPS
cout<<"7 * "<<i<<" = "<<t[i]<<endl;
#elif defined USING_OTHER_STL
cout<<"7 * "<<i<<" = "<<*t_iter<<endl;
#else
assert(0);
#endif
}
return
0;
}


typedef
int Multiplier; //int is also now written as Multiplier

//This program creates a multiplication table of the number input from 1 to 10
table multiplicationTableTill10(int num)
{

table t;
tableIter t_iter;
//3 - Communication: Multiplier is more meaningful then int in the case below
for(Multiplier i = 1; i <= 10; i++)
{

#if defined USING_MAPS
t[i] = num * i;
#elif defined USING_OTHER_STL
t_iter = t.end();
t.insert(t_iter, num * i);
#else
assert(0);
#endif
}
return
t;
}






The Output is as follows:



More information on Typedefs:


Wednesday, 17 February 2010

What is the output of this tricky program?

Interesting problem from C Programming tricks:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

int
a=2,*f1,*f2;
f1=f2=&a;
*
f2+=*f2+=a+=2.5;
*
f1+=*f1+=a+=2.5;
cout<<"a = "<<a<<" *f1 = "<<*f1<<" *f2 = "<<*f2<<endl;

return
0;
}






What is the final value of a, *f1 and *f2. Choose one from below:
a) 18,18,18
b) 10,10,10
c) 72,72,72
d) 64,64,64
e) 26,26,26

The answer is...
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.


Wednesday, 10 February 2010

Synchronous and Asynchronous calls in C++

Sometimes there can be confusion between Synchronous and Asynchronous calls. A synchronous call is the one in which the function/call/procedure has to return before the next statement can be executed. What this means is that the function is blocking the rest of the code.

In asynchronous calling, generally there would be multiple threads. So a function call on one thread will probably not block the function call on other thread. That means that both the functions are asynchronous.

Here is a simple example that I have modified from an earlier example to show synchronous and asynchronous calling:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example from http://www.adrianxw.dk/SoftwareSite/Threads/Threads2.html
//This shows an example of Synchronous and Asynchronous function calls
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;

void
Func1(void *);
void
Func2(void *);

CRITICAL_SECTION Section; //This will act as Mutex


int
main()
{

InitializeCriticalSection(&Section);

//Synchronous calling
cout<<"\nSynchronous calling"<<endl;
Func1(0);
Func2(0);

//Asynchronous calling
cout<<"\nAsynchronous calling"<<endl;
HANDLE hThreads[2];

//Create two threads and start them
hThreads[0] = (HANDLE)_beginthread(Func1, 0, NULL);
hThreads[1] = (HANDLE)_beginthread(Func2, 0, NULL);

//Makes sure that both the threads have finished before going further
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);

//This is done after all threads have finished processing
DeleteCriticalSection(&Section);

cout << "Main exit" << endl;
return
0;
}


void
Func1(void *P)
{

int
Count;

for
(Count = 1; Count < 11; Count++)
{

EnterCriticalSection(&Section);
cout << "Func1 loop " << Count << endl;
LeaveCriticalSection(&Section);
Sleep(1000);
}

return
;
}


void
Func2(void *P)
{

int
Count;

for
(Count = 10; Count > 0; Count--)
{

EnterCriticalSection(&Section);
cout << "Func2 loop " << Count << endl;
LeaveCriticalSection(&Section);
Sleep(1000);
}

return
;
}







The output is as follows:

Wednesday, 3 February 2010

reinterpret_cast in C++

From the Cpp Reference:

Syntax: TYPE reinterpret_cast (object);

The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Suppose we have two variables, int a and char b

In C programming we can covert from b to a by:
a = (int)b;

In C++, the proper way to do this would be by using cast. One way is to use:
a = reinterpret_cast(b);

Most of the time reinterpret_cast is not required in the programs and can often be very dangerous. The following is from MSDN:

The reinterpret_cast operator also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

The reinterpret_cast operator cannot cast away the const, volatile, or __unaligned attributes. See const_cast Operator for information on removing these attributes.

The reinterpret_cast operator converts a null pointer value to the null pointer value of the destination type.

One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.

Instead of reinterpret_cast people generally prefer static_cast

Lets look at an example of reinterpret_cast:





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

int
a = 22;
float
b = (float)33.3333;

cout<<"1. a = "<< a <<" b = "<< b <<endl;

a = (int)b; //Old C programming way
cout<<"2. a = "<< a <<" b = "<< b <<endl;

//Wont work in this case because floating point format is different
a = reinterpret_cast<int&>(b);
cout<<"3. a = "<< a <<" b = "<< b <<endl;

a = static_cast<int>(b); //Correct approach
cout<<"4. a = "<< a <<" b = "<< b <<endl;

char
c;
//Convert int to char
c = reinterpret_cast<char&>(a);
cout<<"5. c = "<< (int)c <<" a = "<< a <<endl;

//Dangerous to convert from char to int
a = reinterpret_cast<int&>(c);
cout<<"6. c = "<< (int)c <<" a = "<< a <<endl;

//What we actually wanted was just the last 8 bits so...
a = a & 0x000000FF; //00 = 8 bits
cout<<"7. c = "<< (int)c <<" a = "<< a <<endl;

return
0;
}






The output is as follows: