Thursday, October 31, 2013

auto variable in C++ 11

C++ 11 standard made lot many improvements to C++. New features like rvalue reference, lambda functions, auto variable and many more added to C++. There was auto variable in previous C++ also, but that has completely new meaning now. C++ 11 standard committee members, which also includes big organizations like, Microsoft, Apple, Google, IBM, decided C++98 auto variable is pretty useless, and new meaning can be given to auto keyword with little impact.

In this article we will discuss about auto variables.

Let’s start simple first,

       int i = 10;
       auto a = 10;

       cout<<typeid(i).name() << " "<<typeid(a).name()<<endl;// int int

We have explicitly mentioned ‘i’ as integer. For variable ‘a’ we left to compiler to decide its type.  As 10 is integer, type of a would be int. So cout will print ‘int int’ as output.
Let’s take bit complex example,

       vector<int> v;

       v.push_back(1);
       v.push_back(2);
       v.push_back(3);
       v.push_back(4);
       v.push_back(5);

       //print all elements of vector -- old C++ way
       for(vector<int>::iterator it = v.begin();it!= v.end(); it++)
       {
              cout<<*it;
       }

       //print all elements of vector -- used C++ 11 auto
       for(auto it = v.begin(); it != v.end(); it++)
       {
              cout<<*it;
       }

You can see how clumsy looking iterator variable definition can be easily replaced by auto keyword. You need not to explicitly specify which container you are using, and no need to remember what it contains, just v.begin() tells compiler its type.

At very least it makes code look cleaner.

One thing I wanted to bring to notice that C++ is statically typed language, and compiler has to know data type of object at compile time. So, data type of auto variables will also be decided at compile time only.
There are more concrete reasons to use auto variable with lambda functions that I will cover in article for lambda functions.


If you have any queries or suggestions, please put comments below. 

Saturday, August 24, 2013

C++ style casts

C++ Style Casts


C style casting can be abused in many ways. First without much effort one can change type of variable or expression, secondly it is hard to identify where type casting is used, because you just need parenthesis and identifier to do type casting. It is difficult to distinguish normal expression and type casting in C source code, so text finding tools will also be of little help.
C style cast cannot be completely blamed because it was good with C code; C++ has inheritance and polymorphism, which were foreign concepts for C, so there was no reason for C to distinguish between upcasting and downcasting.  
To overcome these issues C++ came up with four new casting keywords viz., static_cast,   dynamic_cast, const_cast, reinterpret_cast.

1.     static_cast


This is general purpose cast, and generally used for casting like from int to double. So whenever you want to typecast, you most of time end up using static_cast. Let’s take following expression,
double b = (double)10/20; /*C style cast from int to double */
double b = static_cast<double> (10) /20; // C++ style cast
Looks clumsy! Yes it is. This is blessing in disguised. It is not easy to read and write syntax, and so you can easily distinguish type casting from other code, secondly all static_cast can be easily found using ‘text search’ tools.
See following code to understand how to use static_cast in C++ program.
#include "stdafx.h"
#include <iostream>
using namespace std;

int main(int argccharargv[])
{
   int a = 10;
   int b = 20;

   double d = static_cast<double>(a)/b;

   cout<<d;
   return 0;
}
Output: 0.5

2.     const_cast


Consider following code snippet
const int a = 10;
int *b = static_cast<int*>(&a); //error static_cast cannot takeaway constness
Problem with above code you are trying to take away const-ness using static_cast and C++ won’t allow this. For this there is special keyword and that is const_cast. Rewritting above code as,
const int a = 10;
int *b = const_cast<int*>(&a);//works fine
Compiler will accept this happily. So, if you want to take away const or volatile use const_cast and not any other cast.
So there is one more advantage of using C++ style cast, that you need to consciously decide and specify what you intent to do. In C there is no such distinction.

3.     dynamic_cast


Upcasting in is perfectly acceptable, since it is casting to generalized type in hierarchy. While doing downcasting may not be always correct. dynamic_cast prevents form incorrect downcasting. If casting is valid result of dynamic cast is valid pointer, otherwise it returns null. Consider following code,
#include <iostream>
using namespace std;

class shape{public :virtual ~shape(){}};
class circle:public shape{};
class square:public shape{};

int main(int argccharargv[])
{
   shape *b = new circle//Upcasting
   square* s = dynamic_cast<square*> (b);//downcasting to incorrect type
  
   (s!=NULL)?cout<<"Right cast"<<endl:cout<<"Wrong cast"<<endl;
  
    circle *c = dynamic_cast<circle*> (b);//downcasting to correct type
  
   (c!=NULL)?cout<<"Right cast"<<endl:cout<<"Wrong cast"<<endl;

   return 0;
}
Output : Wrong Cast
             Right Cast
In program, first we have upcasted circle pointer to shape which is perfectly acceptable, then we are trying to downcast upcasted circle pointer to square pointer using dynamic_cast which is not acceptable as it is incorrect conversion. Finally we downcast upcasted circle pointer to circle pointer using dynamic_cast, which is perfectly acceptable.
Remember, with old style cast both the casting (from circle to circle and from square to circle) is permissible, and program is leaved to its fate.

4.     reinterpret_cast


This is unsafe. It can convert int to pointer and any class pointer to any class pointer. Hope you understand ;). When you convert from any unrelated type to any unrelated type, no one guarantees expected output. Unpredictable behavior. For sake of completeness of article, with advice of not to use it, see following example of reinterpret_cast.
#include <iostream>
using namespace std;


int main(int argccharargv[])
{
   int a = 0x1233254;
   char *ptr = reinterpret_cast<char*> (a);
   *ptr = 3;
   cout<<"Enjoy!!";
   return 0;
}
So, we have covered all types of C++ style cast.
Please add comments below, about your suggestions and views on this.
Happy programming!!