Monday, July 20, 2009

[C++] Playing with the preprocessor directives

Hi,

This was something I shared with my friends when I worked in Juno Online. Thought it'd be interesting to share it with rest of the world! Without much waiting, here we go -

We have the following 3 files:
--file1.h--
#ifndef __file1_h
#define __file1_h
#include <iostream>

struct S
{
#ifdef _SRINI
int a;
#endif
int b;

void Assign(int x, int y)
{
#ifdef _SRINI
a=x;
#endif
b=y;
}

void Print()
{
#ifdef _SRINI
std::cout<<"a="<<a<<std::endl;
#endif
std::cout<<"b="<<b<<std::endl;
}
};

void Assign(int,int);

#endif


--file1.cpp--
#include "file1.h"

S s;

void Assign(int x, int y)
{
s.Assign(x,y);
}

--file2.cpp--
#include "file1.h"

int main()
{
extern S s;
Assign(1,2);
s.Print();
return 0;
}


Compile using the commands:
g++ -D_SRINI -c file1.cpp
g++ -c file2.cpp
g++ -o file file1.o file2.o


What do you expect when you run the 'file' binary?
Will it result in a compilation error?

Or will it output:
a=1
b=2 ?
Or is it just "b=2" ?

But actually the output will be "b=1". Let me reason it out.

According the file1.o, the "struct S" is defined as:
struct S {
int a;
int b;

void Assign(int x, int y)
{
a=x;
b=y;
}

void Print()
{
std::cout<<"a="<<a<<std::endl;
std::cout<<"b="<<b<<std::endl;
}
};


but according to file2.o the "struct S" is defined as:
struct S {
int b;

void Assign(int x, int y)
{
b=y;
}

void Print()
{
std::cout<<"b="<<b<<std::endl;
}
};


Now when main() calls Assign(1,2) of file1.0, the struct S sets a=1 and b=2 according to file1.o's definition. In the viewpoint of struct S, it has initialized its FIRST member to 1 and SECOND member to 2.
When Print() is invoked by main(), file2.o's version of struct S is being used. But this structure has only one member, i.e. 'b'. Since struct S knows that its first value is 1, it doesn't care about the variable name, it just prints 'b=1'.

To reconfirm this, if you set the datatype of 'a' to 'char', the output will contain the ASCII value of the character stored in 'a'.

Until we meet again,
- Srini -

No comments:

Post a Comment