About Me

My photo
I'm a colonist who has declared war on machines and intend to conquer them some day. You'll often find me deep in the trenches fighting off bugs and ugly defects in code. When I'm not tappity-tapping at my WMD (also, known as keyboard), you'll find me chatting with friends, reading comics or playing a PC game.

Wednesday, February 27, 2008

const pointers and typedef

(Reader Level : Beginner)
(Knowledge assumptions : Pointers, typedef, std::vector...)

Sometimes we create our own types using the typedef keyword in C++. For eg;
typedef std::vector<int> INTVECTOR;

If we write : const INTVECTOR myVector;
It is the same as : const std::vector<int> myVector;
This means that the type (in this case, a vector of ints) itself is constant and we can't do stuff like this:
myVector.push_back(10);

Let's look at a typedef for a pointer.
typedef int* INTPTR

If we write : const INTPTR pInt;
Is it equivalent to writing? : const int* pInt;
To answer that we need to think about what these two statements syntactically mean.

In the former statement, we are saying that the type (in this case, the integer pointer) itself is constant and that we can't change it in anyway. That statement prevents us from doing stuff like this: pInt++;

In the second statement, we are informing the compiler that the value that the pointer "points" to is constant.
That means we CAN do : pInt++;
But we can't do : *pInt = 20;

In other words,
const INTPTR pInt; is equivalent to int* const pInt;

Monday, February 25, 2008

Defining a user-defined type within a templated class definition

(Reader Level : Intermediate)
(Knowledge assumptions : Classes, Templates, Structures...)

Ever tried declaring a class, structure, array or an enum within a templated class? Perhaps, the code could be something like this:
template<class T>
class MyClass
{
public:
struct MyStruct
{
T m_d1, m_d2, m_d3;
};

const MyStruct& GetStructure() const;

private:
MyStruct m_struct;
};

template<class T>
const MyClass<T>::MyStruct& MyClass<T>::GetStructure() const
{
return m_struct;
}

MyStruct is not a general-purpose structure. It's used primarily for MyClass. So, it makes sense to scope it within MyClass itself. However, this code will not compile. The following errors were reported by the Microsoft Visual Studio 2005 compiler.
warning: 'MyClass::MyStruct' : dependent name is not a type
error: syntax error : missing ';' before '&'
error: missing type specifier - int assumed. Note: C++ does not support default-int
fatal error: unable to recover from previous error(s); stopping compilation


Clearly the cause of this lies in the fact that the compiler can't discern the type of MyStruct in the GetStructure() definition. A look at the standards provides the solution. The relevant citation is from Section 14.6:
"When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1) and its nested-name-specifier depends on a template-parameter (14.6.2), it shall be prefixed by the keyword typename, forming a typename-specifier."

The revised GetStructure() definition for MyClass should be as follows:
template<class T>
const typename MyClass<T>::MyStruct& MyClass<T>::GetStructure() const
{
return m_struct;
}

Tuesday, February 12, 2008

The Pimpl pattern

(Reader Level : Beginner)
(Knowledge assumptions : Classes, Pointers...)

The Private Implementation (Pimpl) pattern allows the implementation of a whole interface without the need to recompile the modules which use it. As with most design patterns, this pattern can best be explained with an example. Let's say that we have a class named Student. Our Student class is very popular in our project because many other classes use it. The header file of the Student class, "Student.h" may be as follows:
#ifndef STUDENT_HEADER
#define STUDENT_HEADER

#include <string>

class Student
{
private:
std::string m_name;
};

#endif

We may have many classes that contain instances of Student. For example, a Subject class may have an aggregation of Students. So, each of the classes that contain Student(s) would probably have to include "Student.h". Now let's say that at some point in time, colleges allow students to carry mobile phones freely (I know that's not likely. :D). Now, our Student will have a contact number that we might want to record. Professors already had mobiles all along. So, let's say that we already have a class named ContactNo that stores all types of numbers, be they Landline, Mobile or Pagers. "Student.h" becomes...
#ifndef STUDENT_HEADER
#define STUDENT_HEADER

#include <string>
#include "ContactNo.h"

class Student
{
private:
std::string m_name;
ContactNo m_contactNo;
};

#endif

After making the relevant changes, we need to do a full re-compile of the source. To our dismay, we might find that the compile time has become unbearably long. Why? It's because we included "Contact.h" in our popular "Student.h". With that one simple change, the header files of all the classes that used to just include "Student.h" will now also include "Contact.h". If our Student was that popular, then this might mean a lot of unnecessary inclusions. To add insult to injury, the contact number of the Student might never even be used by many classes. For example, our Subject class would have no reason to know the contact number of the Students who take that subject. That's why m_contactNo is a private member of Student. You might think that the entire situation is a bit contrived but I assure you its not and there can be situations where you might desperately be seeking a way to reduce compile times, especially in the case of large projects. This is where the Pimpl pattern comes in. Basically, what we need to somehow achieve is the removal of "ContactNo.h" from "Student.h". What we do is take the private implementation of the class (in our case, m_contactNo of Student) and pack it into a simple internal structure. A pointer to this structure, called an opaque pointer or d-pointer is then made a private member of the class. We also need to take care of dynamically creating and destroying the implementation structure for every object of the wrapping class.

This is then our "Student.h" file with the Pimpl pattern.
#ifndef STUDENT_HEADER
#define STUDENT_HEADER

#include <string>

class Student
{
private:
std::string m_name;
struct PIMPL; //Forward declaration.
PIMPL* pimpl; //The opaque pointer.

public:
Student();
~Student();
};

#endif

Our "Student.cpp" file could be:
#include "Student.h"
#include "ContactNo.h"

//Private Implementation structure.
struct Student::PIMPL
{
ContactNo m_contactNo;
};

Student::Student()
{
pimpl = new PIMPL;
}

Student::~Student()
{
if(pimpl)
delete pimpl;
}

If we want to access the contact number of the student internally we do it as pimpl->m_contactNo. Now that we've seen how useful the Pimpl pattern can be, let's talk about its downside. By using the Pimpl pattern, our code has become a little more complex (less readable anyway) and we've also got to do a dynamic allocation for every instance of Student that is created. For large objects with relatively fewer instances, this probably won't be an issue but for small objects with several instances, Pimpl may not fit the bill.

Sunday, January 20, 2008

Album recommendation - The Goo Goo Dolls

Music is a funny thing...Normally, you go out and buy an album because you like one particular song that's been playing over and over on VH1. When you do buy the album, you realise that the rest of the tracks suck (not always). After a little while, even the song that you really liked isn't so nice anymore because its been done to death on TV. That's why its always a good idea to do a little background check on music. There are lots of sites out there that let you preview a 30 seconds of each track before you buy the album. Use this feature. You'll be able to make a better decision. Unless you're a die-hard fan of the artist, always make sure that the tracks measure up to your taste in music.

That said, I have an album recommendation to make. If there's anyone out there who's into Alternative Rock, give The Goo Goo Dolls a listen. I really love this band and one of my favourite albums is Let Love In. I'm not going to write a review on any of the songs simply because one man's symphony is another man's cacophony.

Sunday, January 13, 2008

MI isn't Mission Impossible

I don't want to start a war of ideas on whether Multiple Inheritance is a good thing or not. I know several good programmers who can't get along without multiple inheritance and there are other smart people who feel that multiple inheritance is detrimental to their work. At the end of the day, it comes down to the simple truth that multiple inheritance is not evil in itself, its the way you use it. Sure, it can trip you up in ways you never thought of before but it can also be a very powerful language feature that makes code more elegant and reusable. A while back, I wrote an article on the common "gotchas" with multiple inheritance in C++ and submitted it to Codeguru. Please feel free to read the article here.

Wednesday, January 9, 2008

Out with the old stuff, Teach the new stuff

I've always wanted to talk about coding in schools, especially C++. I see many schools and colleges that portray to teach C++, but in reality teach the C-style of coding. I find this approach unacceptable. For example, many courses (even MCA) talk about character arrays when in reality the syllabus should be dealing with std::string. As if that weren't bad enough...

I've also noticed that many educational institutions use archaic compilers for C++ coding. This, in my opinion, is infinitely worse. Even if a student wanted to code correctly, he would not be able to do so. The most commonly used C/C++ compiler is Borland's Turbo C++ 3.0 compiler. This compiler does not conform to the C++ '98 standard. A very simple example of this is the boolean data type which the standards approve of but Turbo C++ does not support it. The truth is that Turbo C++ is an obsolete compiler and Borland themselves do not work on it anymore. Continuing to use such a compiler will ensure that you never learn anything that is industry standard. There are quite a few non-commercial compilers that are standards compliant.
1. The MinGW (Minimalistic GNU for Windows) compiler for Windows.
2. GCC (GNU Compiler Collection) for almost every platform.

If you are a student and don't want the hassle of bothering to download and configure a particular compiler for your IDE, then I recommend these IDEs:
1. Microsoft Visual Studio Express Edition
Its the most professional free IDE out there. Of course, it only works under Windows and comes with the Microsoft Compiler.
2. Code::Blocks
I really love this IDE and the best part is that it works on Windows, Linux and now even the Mac OS. It also supports a variety of compilers.
3. Bloodshed Dev C++ 5.0
A great IDE for students. It comes in two flavours - one with the MinGW compiler and another without any compiler. Dev C++ is also exclusively for Windows.
4. Geany
Geany is a newcomer to the scene and I've really noted it for supporting several languages and being extremely light-weight. Geany is also being actively developed for multiple OS platforms.
5. Finally, if you work on Linux, I recommend either KDevelop or Anjuta. I now use Code::Blocks as a standard IDE for both Windows and Linux, though.

If you're going to do stuff, then you have to do it right.

Monday, January 7, 2008

Start Stuff

Hi all! I've been deliberating for some time on whether I should start a blog or not. I guess I've got stuff to talk about and so I've finally taken the plunge. Here's the Disclaimer : "Nothing I've got to say is earth-shattering. Read at your own risk!" First, a little about myself. I am a student pursuing my Master's Degree in Computer Applications which I am due to complete in a few months. As you might have suspected, I am interested in tech talk. That's not the only stuff that I will talk about, though. I love listening to music and once in a while I will try to suggest and maybe even do a review on a good music album. The main reason as to why I've started this blog is so that I can share ideas and information. A lot of my time is spent in coding and I find out nifty tricks or read about such tricks elsewhere. I also come across coding bugs and perhaps if I post solutions to common problems other programmers could benefit from them. I also want to share my views on certain issues in the digital world (Read as : "I want to start a rant"). I play plenty of PC-based games and maybe once in a while I could talk about some of the games that I play. Of course, I welcome comments. If you find some error in a post of mine or just want to chip in with your view, go ahead. The world will be the better for it. Alright then. After all that's been said, let's start doing stuff.