Archive for November, 2009

Cast Operations in C/C++

November 28, 2009

Lately, i have been looking at my old c/c++ codes. Suddenly i realised that it is quite diffucult to read the code where i have casted different data types to each other by using old style C casting. (Type) Another Type. I Even sometimes cast an integer to an integer pointer. But it is quite hard to read what i am casting into what. So i had a research whether there is something new to casting. And it turns out there was.

Today i am gonna tell you about 4 different casting styles:
1) static_cast
2) const_cast
3) dynamic_cast
4) reinterpret_cast

dynamic_cast (expression)
reinterpret_cast (expression)
static_cast (expression)
const_cast (expression)

    STATIC CAST:

static_cast is the most useful cast. It can be used to perform any implicit cast. When an implicit conversion loses some information, some compilers will produce warnings, and static_cast will eliminate these warnings. Making implicit conversion through static_cast is also useful to resolve ambiguity or to clarify the conversion presence. It also can be used to call an unary constructor, declared as explicit. It also can be used to cast up and down a class hierarchy, like dynamic_cast, except that no runtime checking is performed.

Here is an example:
casting an int to a double for the purpose of avoiding truncation due to integer division:

double result = static_cast(4)/5;

BULLET POINTS ABOUT STATIC CAST:

* Static casts are only available in C++.
* Static casts can be used to convert one type into another, but should not be used for to cast away const-ness or to cast between non-pointer and pointer types.

    CONST CAST:

const_cast is used to apply or remove const or volatile qualifier from a variable.


Here is an example:
casts a const pointer to a non-const pointer to pass into a function:

void func(char *);

const char *x = "abcd";
func(const_cast(x));

BULLET POINTS ABOUT CONST CAST:
*Const casts are only available in C++.
*Const casts are used to strip the const-ness or volatile-ness from a variable.

    DYNAMIC CAST:

dynamic_cast is used on polymorphic pointers or references to move up or down a class hierarchy. Note that dynamic_cast performs runtime-checks: if the object’s type is not the one expected, it will return NULL during a pointer-cast and throw a std::bad_cast exception during a reference-cast.

Here is an example:
class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast(&d); // ok: derived-to-base
pd = dynamic_cast(&b); // wrong: base-to-derived

The second conversion in this piece of code would produce a compilation error since base-to-derived conversions are not allowed with dynamic_cast unless the base class is polymorphic.

Compatibility note: dynamic_cast requires the Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using dynamic_cast to work properly.

    REINTERPRET CAST:

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked.

It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it, is granted to be able to be cast back to a valid pointer.

The conversions that can be performed by reinterpret_cast but not by static_cast have no specific uses in C++ are low-level operations, whose interpretation results in code which is generally system-specific, and thus non-portable. For example:

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast(a);

This is valid C++ code, although it does not make much sense, since now we have a pointer that points to an object of an incompatible class, and thus dereferencing it is unsafe.

One Last Thing as An Type Identifier :

typeid (expression)

This operator returns a reference to a constant object of type type_info that is defined in the standard header file . This returned value can be compared with another one using operators == and != or can serve to obtain a null-terminated character sequence representing the data type or class name by using its name() member.

// typeid
#include
#include
using namespace std;

int main () {
int * a,b;
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}

RESULT:


a and b are of different types:
a is: int *
b is: int

When typeid is applied to classes typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:

// typeid, polymorphic class
#include
#include
#include
using namespace std;

class CBase { virtual void f(){} };
class CDerived : public CBase {};

int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " << e.what() << endl; }
return 0;
}

Result:

a is: class CBase *
b is: class CBase *
*a is: class CBase
*b is: class CDerived

Notice how the type that typeid considers for pointers is the pointer type itself (both a and b are of type class CBase *). However, when typeid is applied to objects (like *a and *b) typeid yields their dynamic type (i.e. the type of their most derived complete object).

If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value, typeid throws a bad_typeid exception.

Links:
http://www.cplusplus.com/doc/tutorial/typecasting/
http://www.cprogramming.com/reference/typecasting/
http://www.cppreference.com/wiki/keywords/casting_comparison

Creating an Ad-Hoc Network Between Two Open-Suse Installed Computers

November 25, 2009

Hi fellows,

Lately my wireless router broke down and i sent it to be repaired. But the problems started to arise because without a wireless router i wasn’t able to share my Internet connection. So i had it on my mind that i can solve this problem by connecting only one computer directly to the modem and making an ad-hoc connection between the remaining computers and sharing the Internet. So the problem’s first phase was to setup an ad-hoc network, Since all my OS’s are OPENSUSE (I like to pronounce it like “Susie”,because this reminds me my dream girl) , this tutorial will show you how to setup an ad-hoc network between openSUSE installed machines. Then in another tutorial I will teach you how to share Internet connection.

There are 3 ways to do this :

1) Ad-Hoc connection setup with Network Manager. (Probably the easiest)

Do the things on the computer which directly connects to modem :

  • Left click on the Network Manager icon and select Create New Wireless Network
  • Specify an ad-hoc network name. For example: “VEB61”
  • Select security method
  • Click the Create button
  • Right click on the Network Manager icon, select Edit Connections.
  • Select the Wireless tab, select the ad hoc network name and click the edit button.
  • On the Wireless tab set the mode to Ad-hoc
  • Select the Ipv4 Settings tab select the Manual method in the drop down
  • Click the Add button and enter a local IP address, Net mask and Gateway, i.e. 192.168.0.1, 255.255.255.0, and 192.168.0.1 respectively.
  • Leave DNS Servers and Search Domains blank
  • Click Apply
  • Left click on the Network Manager icon and select Connect to Hidden Wireless Network
  • Select ad hoc network name on the connection drop down and click Connect.

 

On the other computers :

  • Left click on the Network Manager icon and select Connect to Hidden Wireless Network
  • TYPE “VEB61” and click connect. (Ad hoc network name created above.)
  • Right click on the Network Manager icon, select Edit Connections.
  • Select the Wireless tab, select the ad hoc network name and click the edit button.
  • On the Wireless tab set the mode to Ad-hoc
  • Select the Ipv4 Settings tab select the Manual method in the drop down
  • Click the Add button and enter a local IP address, Net mask and Gateway, i.e. 192.168.0.1, 255.255.255.0, and 192.168.0.2 respectively.
    • Note: The IP address for every machine must be different
  • Leave DNS Servers and Search Domains blank
  • Click Apply

2) Ad-Hoc connection setup without Network Manager.

 

  • in YaST disable Network Manager (NM)
  • as a root bring down the wireless interface
# ip link set wlan0 down
  • set the domain id and set the ad-hoc mode
# iwconfig wlan0 essid VEB61 mode Ad-Hoc
  • bring up the interface
# ip link set wlan0 up
  • set the IP address manually
# ip link addr add 192.168.102.1/24 dev wlan0
  • Repeat the procedure on all interfaces that should communicate together. Select unique IP address for each interface.

 

2) Ad-Hoc connection setup with Yast.

  • YaST -> Network devices -> Network Card
  • select ifup, click Next
  • select card, Edit
  • select “Static address setup” and fill up the IP address, Next
  • select “Operating Mode” Ad-Hoc and set ESSID to your domain id
  • select authentication, Next, Finish
  • Repeat on all interfaces.