C++ Programming: Cross Casts

A multiply inherited class object can be converted into a second base class.

For ex:


struct A
{
int i;
virtual ~A () {}
};

struct B { bool b; };

struct D: public A, public B
{
int k;
D() { b = true; i = k = 0; }
};

A *ptra = new D;
B *ptrb = dynamic_cast< B* >ptra;

The static type for ptra is A * where as the dynamic type is D *. Normal static cast can't be used here as A and B are two different structures. reinterpret_cast<> will result in simply assigning ptra to ptrb. But the address of B subobject and A subobject in D are different. So to do so we have to calculate the address of B at runtime which can be achieved by dynamic_cast<>

Labels:

Posted by - at 8:17 pm | 0 comments read on

Programming - Must Read Books

The Shellcoder's Handbook : Discovering and Exploiting Security Holes
Shellcoder's Programming Uncovered
Hacker's Delight
Programming Interviews Exposed: Secrets to Landing Your Next Job
Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions
More Exceptional C++
Posted by - at 2:27 am | 0 comments read on

C++ Programming - Inline or Macro

A function defined within the declaration of a class is inline by default. When no inline specifier is used, linkage will be external unless an inline definition appears before the first call.
Inline function should only have exactly one definition.



  • Expansion of Arguments can give weird result or compile time errors while using MACRO
  • MACROS has the ability to operate on any type of arguments.
  • Both MACROS and inlining has a problem that the callers of an inline/MACRO has to recompiled
  • Both exposes implementation details.

Labels:

Posted by - at 2:00 am | 0 comments read on

C Programming - The Assert Macro

assert () marcro takes a boolean-valued expression evalutes to true, but it prints an informative message and terminates the program if expression eveluates to false. If using C++ you can avoid the deprecated warning message by using instead of

eg:
assert ( ptr == NULL );

Labels:

Posted by - at 1:56 am | 0 comments read on

C++ Programming - Unnamed Bit-Field

An unnamed bit field is used for padding to conform to external imposed layouts.

Unnamed bit-field with a width of zero specifies aloignment of the next bit field at an allocation unit boundary.

struct becks {
...
int :3 //three bit field
...
}

Labels:

Posted by - at 1:53 am | 0 comments read on

C++ Programming - Class Member Alignment

class A {
bool a;
int b;
bool c;
};


class B {
bool a;
bool c;
int b;
};

What will be the value of sizeof(A) and sizeof(B)?

Labels:

Posted by - at 4:50 am | 0 comments read on

C Programming - Stack

Note: Almost all the cases explained below are for intel x86 under linux platform and compiled using gcc.

The stack is LIFO data structure. Stack boundary is defined by extended stack pointer (ESP) register. In over case ESP points to the last address used on the stack, whereas there as architectures in which it points to the first free address.

Suppose we call a function f(1,2,3) from our main program. What happens behind the scenes is as follows.

1. Push the arguments in the reverse order ( eg. 3,2 and 1)

2. Then the function is invoked (CALL), which places the return address into stack, i.e. the current extended instruction pointer register (EIP). This is place where the function should ret when it executes return statement or rather RET opcode.


3. Current value of extended base pointer register (EBP) is pushed into the stack, this is also referred to as stack frame pointer. EBP is used for relative addressing of element in stack. When the calle function returns it is used to refer the elements of the stack of caller function.

4. Once EBP is stored on the stack, we move the current ESP to EBP for refering the elements local to the current stack frame.

5. Reserve the address space required for the local variables of the function.

Labels:

Posted by - at 1:51 am | 1 comments read on

C++ Programming - Unions in C++

Default access to a union is public, it can contain member functions and member data.

Other than that there are some more specialties for unions in C++.


  • It can't have a static data members or a member of reference type.
  • It can't have virtual functions.
  • It can't be used as a base class nor it can have base class.
  • An object of a class with a construct or a destructor or a user-defined assignment operator cannot be a member of a union

Labels:

Posted by - at 1:35 am | 0 comments read on

C++ Programming - Global Anonymous Unions

An anonymous union that is declared in a named namespace or in the global namespace has to be explicitly declared static. For example

static union //anonymous union in global namespace
{
int num;
char *pc;
};
namespace NS
{
static union { double d; bool b;}; //anonymous union in a named namespace
}
int main()
{
NS::d = 0.0;
num = 5;
pc = "str";
return 0;
}

Labels:

Posted by - at 1:33 am | 0 comments read on

C++ Programming - sizeof()

An empty class doesn't have any data members or member functions. Therefore, the size of an instance is seemingly zero. However, C++ guarantees that the size of a complete object is never zero. Consider the following example:

class Empty {};
Empty e; // e occupies at least 1 byte of memory

If an object is allowed to occupy zero bytes of storage, its address can overlap with the address of a different object. The most obvious case is an array of empty objects whose elements all have an identical address. To guarantee that a complete object always has a distinct memory address, a complete object occupies at least one byte of memory. Non-complete objects -- for example, base class subobjects in a derived class -- can occupy zero bytes of memory.

Labels:

Posted by - at 1:33 am | 0 comments read on

C++ Programming - Big Three

Constructor+Destructor+Copy Constructor=Big Three

Labels:

Posted by - at 1:32 am | 0 comments read on

C++ Programming - Pure Virtual Destructors

Unlike ordinary member functions, a virtual destructor is not overridden when it is redefined in a derived class. Rather, it is extended. The lower-most destructor first invokes the destructor of its base class; only then is it executed. Consequently, when you try to declare a pure virtual destructor, you might encounter compilation errors, or worse -- a runtime crash. In this respect, pure virtual destructors are exceptional among pure virtual functions -- they have to be defined. You can refrain from declaring a destructor with the pure specifier, making it only virtual. However, this is an unnecessary design compromise. You can enjoy both worlds by forcing an interface whose members are all pure virtual, including the destructor -- and all this without experiencing runtime crashes. How is it done?

First, the abstract class contains only a declaration of a pure virtual destructor:

class Interface
{
public:
virtual void Open() = 0;
virtual ~Interface() = 0;
};

Somewhere outside the class declaration, the pure virtual destructor has to be defined as follows:

Interface::~Interface()
{} //definition of a pure virtual destructor; should always be empty

Labels:

Posted by - at 1:31 am | 0 comments read on

C++ Programming - Pseudo Destructors

Fundamental types have constructors, as you have seen. In addition, fundamental types also have a pseudo destructor. A pseudo destructor is a syntactic construct whose sole purpose is to satisfy the need of generic algorithms and containers. It is a no-op code that has no real effect on its object. If you examine the assembly code that your compiler produces for a pseudo destructor invocation, you might discover that the compiler simply ignored it. A pseudo destructor invocation is shown in the following example:

typedef int N;
int main()
{
N i = 0;
i.N::~N(); //pseudo destructor invocation
i = 1; //i was not affected by the invocation of the pseudo destructor
return 0;
}

The variable i is defined and initialized. In the following statement, the pseudo destructor of the non-class type N is explicitly invoked but it has no effect on its object. Like the constructors of fundamental types, pseudo destructors enable the user to write code without having to know if a destructor actually exists for a given type.

Labels:

Posted by - at 1:31 am | 0 comments read on

C++ Programming - Destructor Invocation

Destructors are invoked implicitly in the following cases:

* For static objects at program termination
* For local objects when the block in which the object is created exits
* For a temporary object when the lifetime of the temporary object ends
* For objects allocated on the free store using new, through the use of delete
* During stack unwinding that results from an exception

A destructor can also be invoked explicitly. For example:

class C
{
public:
~C() {}
};
void destroy(C& c)
{
c.C::~C(); //explicit destructor activation
}

A destructor can also be explicitly invoked from within a member function of its object:

void C::destroy()
{
this->C::~C();
}

In particular, explicit destructor invocation is necessary for objects that were created by the placement new operator.

Labels:

Posted by - at 1:30 am | 0 comments read on

C++ Programming - Member Initialization Lists

The choice between using a mem-initialization list and initialization inside the constructor's body is significant in the following four cases:

*Initialization of const members
*Initialization of reference members
*Passing arguments to a constructor of a base class or an embedded object
*Initialization of member objects

In the first three cases, a mem-initialization list is mandatory; in the fourth case, it is optional.

The Order Of A Mem-Initialization List Must Match The Order Of Class Member Declarations

Labels:

Posted by - at 1:30 am | 0 comments read on

C++ Programming - Explicit Constructors


class A {
public:
A() { ... };
A(int i) { ... };
};

main()
{
A a;
A b = 1;
...
}


The compiler interprets the expression A b= 1; as if the programmer had written
A b = A(1);


You might encounter a similar problem when calling a function that takes A as argument. The following example can either be a cryptic coding style or simply a programmer's typographical error. However, due to the implicit conversion constructor of class A, it will pass unnoticed:


int f(A a);
int main()
{
f(1); // without a an explicit constructor,
//this call is expanded into: f ( A(1) );
//was that intentional or merely a programmer's typo?
}


In order to avoid such implicit conversions, a constructor that takes one argument needs to be declared explicit:


class A {
public:
A() { ... };
explicit A(int i) { ... };
};

An explicit constructor does not behave as an implicit conversion operator, which enables the compiler to catch the typographical error this time:

int main()
{
A a; //OK
A b = 1;// compile time error ; this time the compiler catches the typo
}

Labels:

Posted by - at 1:29 am | 0 comments read on

Trivial Constructors

A constructor is considered trivial when all the following hold true:

* Its class has no virtual member functions and no virtual base classes.
* All the direct base classes of the constructor's class have trivial constructors.
* All the member objects in the constructor's class have trivial constructors.

Labels:

Posted by - at 1:28 am | 0 comments read on

Archives

  • May 2011
  • February 2009
  • December 2008
  • November 2008
  • October 2008
  • August 2008
  • April 2008
  • December 2007
  • November 2007
  • January 2007
  • December 2006
  • October 2006
  • September 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005

Links