Showing posts with label Preprocessor. Show all posts
Showing posts with label Preprocessor. Show all posts

Wednesday, 21 April 2010

Printing Debug information through Macros

This example shows probably one of the most useful case for using Macro's. Since Macro's are expanded before the code is compiled, debug information like filename and line number is available in the macro to be used.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

#define PRINT_DEBUG_INFO \
cout<<__DATE__<<" "<<__TIME__<<": "<<__FUNCTION__<<", "<<__FILE__<<", "<<__LINE__<<endl;
//Note that __TIMESTAMP__ can be used instead of __DATE__ and __TIME__

void
func1(int* someNum)
{

if
(someNum)
{

//Perform normal operations here
int someVar=0;
}

else

{

//Abnormal scenario
PRINT_DEBUG_INFO;
}
}


void
func2(int *); //forward declaration of func2

int
main()
{

int
*x = NULL;
func1(x); //Creating exception scenario
func2(x); //Creating exception scenario

return
0;
}


void
func2(int* someNum)
{

try

{

//Normal case here
if(someNum)
*
someNum = 100;
else
throw
0;
}

catch
(...) //Abnormal case
{
PRINT_DEBUG_INFO;
}
}





The output is as follows:
Please note that in the above example, the __DATE__ and __TIME_ functions return the compilation date and time, not the current date and time. More details here.

To get the current execution date and time, see this example.

Thursday, 8 October 2009

Using #pragma message directive

Sometimes you would like to remind the user or yourself of something while compiling and there is an option to remind yourself using the #pragma message directive. See the following program:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show how to remember things using #pragma message
#include<iostream>

using namespace
std;

int
someFunction(int a=0, int b=0)
{

#pragma message("TODO: Coding of someFunction()")
return 0;
}


int
main()
{

someFunction();
return
0;
}

In this case the user wants to remind himself that someFunction() needs to be coded at a later time and hence he uses a preprocessor message statement. The result is when compilation is done, a message will be output as shown below:

Tuesday, 6 October 2009

Using Preprocessor Statements #ifdef, #elif, #else and #endif

Sometimes it becomes necessary to write two (or more) different peices of behaviour in a common code. Depending of its mode/place/time/version the behaviour has to be changed. It can be done by the use of simple preprocessor statements. Consider the following program:






//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show use of preprocessor macros for dynamic behaviour

#include<iostream>
#include<string>

using namespace
std;

#define USE_CAR //Comment or Uncomment this if using preprocessor option

int
main()
{

int
someNum = 3;
#ifdef USE_CAR
string modeOfTransport("Use a Car");
#elif USE_BUS
string modeOfTransport("Use a Bus");
#elif USE_TRAIN
string modeOfTransport("Use a Train");
#else
string modeOfTransport("Use any mode of transport");
#endif

cout<<"Mode of Transport = "<<modeOfTransport<<" and someNum = "<<someNum<<endl;

return
0;
}



The output is as follows:

In the program above, the statement in the start #define USE_CAR says that the code with USE_CAR should be used during compile time. Instead if USE_BUS is defined, that particular peice of code will be used. If nothing is defined then the behaviour with else will be used.

There is another way to use these preprocessor directives. It is by defining in the properties below. If defined this way then the statement should be omitted from the main program.


The output is as follows in this case:

For more information see this.

Friday, 7 August 2009

Suppress Compiler Warning using #pragma

Ocassionally the compiler can throw out warnings which may be informative to you but you do not want others to see. You can use a #pragma directive to suppress the warnings. An example of the code below:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

//This example shows how to suppress warnings using #pragma

#include<iostream>



using namespace
std;



class
error

{


public
:

error(string s)

{


info = s;

}


private
:

error();

string info;

};




#pragma warning( disable : 4290 )



int
someFunc(void) throw (error)

{


return
1;

}




#pragma warning( default : 4290 )



int
someOtherFunc(void) throw (error)

{


return
1;

}




int
main()

{




return
0;

}




Here, for 'someOtherFunc', the compiler will generate a warning:


warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)


but a similar warning for 'someFunc' wont be generated because we have already suppressed it using the #pragma.


Monday, 15 June 2009

Avoiding Redifinition using #pragma once

Lets write a very simple program where there is main.cpp that includes classA.h and classB.h. classA.h contains class A and classB.h contains class B.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show how to avoid redifinition problems
#include <iostream>
#include "classA.h"
#include "classB.h"

using namespace
std;

int
main()
{

A a;
B b;
a.a = 20; //some stuff not relevant here
b.a = 40; //some stuff not relevant here
return 0;
}

//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//A very simple example class that does nothing
class A
{

public
:
int
a;
int
b;
private
:
int
c;
};
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//A very simple example class that does nothing
#include "classA.h"

class
B :public A
{

private
:
int
d;
};

When we try to compile this, the compiler complains as follows:




To get round this problem, in each of the include file we can use a #define as follows

#ifndef _CLASSA_H_

#define _CLASSA_H

//Some code

#endif //_CLASSA_H

In C++ we can also write #pragma once. Using #pragma once can increase compilation speed and the compilor may optimise the code as the use of pre-processor can be removed. So the class A in our program giving problem can now be modified as follows for the program to compile properly:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//A very simple example class that does nothing
#pragma once
class A
{

public
:
int
a;
int
b;
private
:
int
c;
};