EventHelix.com: CASE Tools; Real-time and Embedded System Design; Object Oriented Design
  Home  |  EventStudio System Designer 4.0  |  VisualEther Protocol Analyzer 1.0  Real-time Mantra  Contact Us  AddThis Social Bookmark Button

Home > Real-time Mantra > Object Oriented Design > C++ and C (Classes and Methods)
Comparing C++ and C (Classes and Methods)

This two part series compares C and C++ by comparing the C++ code and its equivalent C code. This comparison should give you a better feel of the performance differences between C and C++.

C++ Method Invocations 

 In the first article in this series we will look at the performance impact of C++ method invocations. This comparison will be carried out by first comparing C++ code and its C equivalent.

C++ Code

// Example class A contains regular and

// static member variables and methods.

 

class A

{

private:

  int m_x;

  static int g_y;

  int m_z;

 

  // Should be invoked when the object ends

  void InformEnd();

 

public:

  A(int x);

  ~A();

  void UpdateX(int newX);

  static void UpdateY(int newY);

};

 

// Initialization of the static variable

int A::g_y = 0;

 

// The non-static member variables

// are initialized in the constructor

A::A(int x)

{

  m_x = x;

  m_z = 0;

}

 

// Destructor invokes a private variable

A::~A()

{

  InformEnd();

}

 

// UpdateX checks the value of X against

// a static variable before updating the value

void A::UpdateX(int newX)

{

  if (g_y != 0 && m_x < newX)

  {

    m_x = newX;

  }

}

 

// Unconditional update of static variable m_y

void A::UpdateY(int newY)

{

  g_y = newY;

}

 

main()

{

    // Create a object on the heap

    A *pA = new A(5);

 

    // Create an object on the stack

    A a(6);

 

    // Example of an access via a pointer

    pA->UpdateX(8);

 

    // Example of a direct access

    a.UpdateX(9);

 

    // Example of static method call

    A::UpdateY(1000);

 

    // Deleting the object

    delete pA;

}

The following C code provides an equivalent implementation for the C++ code shown above. The C++ class has been mapped to a C structure.

C Code

/*

This code maps from the C++ code to the equivalent C code.

Mapping of the following entities is covered:

- classes                 - methods

- this pointer            - member variables

- constructors            - static methods

- destructors             - static variables

*/

 

#include <stdio.h>

#include <stdlib.h>

#define TRUE 1

#define FALSE 0

typedef int BOOLEAN;

 

/*

Structure A represents the class A. Only the non-static member

variables are present in the structure

*/

struct A

{

  int m_x;

  int m_z;

};

 

/* Notice that g_y is not a part of struct A. Its a separate global variable. */

int g_y = 0;

 

/*

Prototype for the InformEnd method. The C++ version of this method

did not have any parameters but the C mapped function needs the this

pointer to obtain the address of the object. Note that all non-static

methods in the C++ code would map to a C function the additional this

pointer as the first parameter.

*/

void InformEnd(A *this_ptr);

 

/*

The constructor maps to function with the this pointer and the size of the

structure as parameters. this_ptr passed to the constructor is NULL when

the operator new is used to create the object. this_ptr contains a valid

pointer if the memory for the object to be constructed is already

allocated. (e.g. local variable or part of another structure.)

*/

A *A_Constructor(A *this_ptr, int x)

{

  /*Check if memory has been allocated for struct A. */

  if (this_ptr == NULL)

  {

    /*Allocate memory of size A. */

    this_ptr = (A *) malloc(sizeof(A));

  }

 

  /* Once the memory has been allocated for A, initialise members of A. */

  if (this_ptr)

  {

    this_ptr->m_x = x;

    this_ptr->m_z = 0;

  }

  return this_ptr;

}

 

/*

The following function is equivalent to a destructor. The this

pointer and a dynamic flag are passed as the two parameters to

this function. The dynamic flag is set to true if the object is

being deleted using the delete operator.

*/

void A_Destructor(A *this_ptr, BOOLEAN dynamic)

{

  InformEnd(this_ptr);

 

  /* If the memory was dynamically allocated for A, explicitly free it. */

  if (dynamic)

  {

    free(this_ptr);

  }

}

 

/*

A pointer this is passed as first argument. All member variables

in the code will be accessed through an indirecion from the this

pointer. Notice that static variables are accessed directly as

they do not belong to any instance.

*/

void A_UpdateX(A *this_ptr, int newX)

{

  if (g_y != 0 && this_ptr->m_x < newX)

  {

    this_ptr->m_x = newX;

  }

}

 

/*

Notice that this is not passed here. This is so because

A_UpdateY is a static function. This function can only access

other static functions and static or global variables. This

function cannot access any member variables or methods of class A

as a static function does not correspond to an instance.

*/

void A_UpdateY(int newY)

{

  g_y = newY;

}

 

main()

{

    /*

    Dynamically allocate memory by passing NULL in this arguement.

    Also initialize members of struct pointed to by pA.

    */

    A *pA = A_Constructor(NULL, 5);

 

    /* Define local variable a of type struct A. */

    A a;

 

    /*

    Initialize members of struct variable a. Note that the

    constructor is called with the address of the object as

    a has been pre-allocated on the stack.

    */

    A_Constructor(&a, 6);

 

    /*

    Method invocations in C++ are handled by calling the

    corresponding C functions with the object pointer.

    */

    A_UpdateX(pA, 8);

    A_UpdateX(&a, 9);

 

    /* UpdateY is a static method, so object pointer is not passed */

    A_UpdateY(1000);

 

    /*

    Delete memory pointed to by pA (explicit delete in

    original code).

    */

    A_Destructor(pA, TRUE);

 

    /*

    Since memory was allocated on the stack for local struct 

    variable a, it will be deallocated when a goes out of scope.

    The destructor will also be invoked. Notice that dynamic flag

    is set to false so that the destructor does not try to

    free memory.

    */

    A_Destructor(&a, FALSE);

}     

 

Analysis

This section analyses the C++ code and its C translation and identifies the performance impact.

C++ Method Invocation All C++ methods when translated to C end up with an additional parameter. This might appear to be a big performance overhead. In reality however, the code in C will also have to access the common data structure via an array index or some other mechanism.
 
Object Construction Whenever an object is constructed, C++ will invoke the constructor. Sometimes this might be an addition overhead. This overhead can be reduced by defining the constructor inline. In most cases however, the constructor is actually replacing a routine that would have been used to initialize the data structures in a conventional C program.

If a program declares a lot of global objects, object construction can be a big overhead at program startup. C++ invokes constructors for all global objects before main() is called.
 

Object Destruction

 

As you can see from the C code, whenever an object goes out of scope or is explicitly deleted, C++ invokes the destructor for the object. This overhead can be reduced by only defining destructors when they are really needed (i.e. some action is required when object is deleted). Inline destructors can also be used to reduce the overhead. 
 
Static Access The C code above shows that static member functions and variables do not correspond to an instance of the object. Thus they are accessed without indirection of the object. This can be useful in defining methods which need C level function call conventions. One good use for static member functions is to implement interrupt service routines (ISRs). ISRs handlers typically need to be C type functions. In most implementations,  C++ static functions can be directly used as ISR handlers.

Explore More

  Home  |  EventStudio System Designer 4.0  |  VisualEther Protocol Analyzer 1.0  Real-time Mantra  Contact Us
Copyright © 2000-2007 EventHelix.com Inc. All Rights Reserved.