You are here:

C++/C++ programming


I am new to this prog. My prog contains statements as given below:
#define COM1 0#define DATA_READY 0x100
#define SETTINGS(0xE0|0x00|0x00|0x03)
#define TRUE 1
#define FALSE 0
I am unable to understand this. Pl.Help me to understand what it represents and where I can find some reference to read?

Well the sort of thing you show is common in C programs. C++ has alternatives that reduce the need to do the sort of things you show.

#define is a preprocessor directive.

Before a C or C++ source file is properly compiled it is preprocessed:

    <source code> -> [pre-processor] -> <preprocessed source code> -> [compiler] -> <object code>

   <DDD>    Data such as a file
   [PPP]    Processing stage

The above flow is somewhat simplified and the exact split between preprocessing and compilation proper is in fact a little less obvious, (the C++ standard in fact enumerates 9 phases (stages) of translation; stages 8 and 9 however are concerned with what generally happens post-compilation such as linking).

The preprocessor is responsible for executing pre-processor directives. These are things like #define that start with a hash (#) character (in fact the line they are on must have a # as the first non-whitespace character - there may be whitespace before and after the #).

The directives include:

   #include for file inclusion
   #if, #ifdef, #ifndef, #else, #elif #endif for conditional compilation
   #error for producing diagnostic messages and failing the translation

and of course:

   #define for defining a macro
   #undef for undefining a macro

A macro definition consists of a name and a definition. During preprocessing all occurrences of a macro name are expanded. That is the name of the macro is replaced by the expansion of the definition. This might be simply replacing the text of the name of the macro with the text of the definition or it might be more complex.

Taking the examples of TRUE and FALSE from your question:

   #define TRUE 1

   #define FALSE 0

After encountering these definitions the preprocessor will replace any text TRUE with 1 and any text FALSE with 0. For example after encountering the definitions above the code:

   int isOK(FALSE);
   if ( 0==SomeFunction() )
       isOK = TRUE;

will become after preprocessing:

   int isOK(0);
   if ( 0==SomeFunction() )
       isOK = 1;

This looks OK until you realise that the preprocessor has no concept of scope, type or context when it performs its substitutions. Consider the following:

   class Item

     // ...


   class ItemCollection
       std::vector<Item>      iItem;


     // ...

     Item const  & GetItem() const;
     Item        & GetItem();

OK this will compile, although if you try and use ItemCollection with GetItem the code will not link as there are no definitions for the GetItem member functions.

Assume that this is just part of the full picture and that the code has been in use for a while. Now it is ported to a new platform (operating system). On this platform the header file defining ItemCollection requires a system header file for the new platform. This header contains a preprocessor macro definition, maybe like so:

   #define Item  0x00001028

Next thing you know you have the person doing the porting asking what is going on as the code does not compile on their system using their compiler. The reason is that what the compiler sees for this platform is as follows:

   class 0x00001028

   class ItemCollection
       std::vector<0x00001028>      iItem;



     0x00001028 const  & GetItem() const;
     0x00001028        & GetItem();

The above I copied and pasted from a pre-processor output file produced by compiling the code using MSVC++ 2005 with the /EP and /p options. You will notice the comments have been removed, as had the

   #define Item  0x00001028

macro definition as such things are only for the benefit of the preprocessor the compiler proper never sees them.

The above is a little contrived but I had almost exactly the described experience having written a class for a project initially for MS Windows (16 bit - it was quite some time ago), moved onto a new project (or two), and then having an Apple Mac developer come by asking just such questions. It seems the Mac development environment #defined some macros with very short, common names.

So as you can see using macro names that may conflict with actual program identifiers can cause chaos. This is why macro names are often specified in house coding guidelines to be the only identifiers that are all UPPER_CASE with language proper names (names of functions, types, objects, namespaces etc.)  using lower_case, camelCase or PascalCase. Also a good idea is not to use simple short names for macros as this again reduces the chance they will clash with other names in inappropriate ways.

One other point. Because the compiler never sees the definition of the macro this means that compiler errors and warning and debuggers never see them as well. So debugging code contained in macros can be very frustrating to say the least (yes you can write macros that generate code; please try not to!).

OK so onto the actual meaning of the macros in your question. Note that by "all occurrences" I mean all occurrences within a source file that has the macro defined (either directly or as a result of including an appropriate header file):

   #define COM1 0#define DATA_READY 0x100
Defines COM1 to be a macro with the definition:

   0#define DATA_READY 0x100
I suspect this should be two macro definitions and a line end went missing somewhere:

   #define COM1 0
   #define DATA_READY 0x100

Defines a macro named COM1 so the preprocessor replaces all occurrences of COM1 with 0 and a macro named DATA_READY so the preprocessor replaces all occurrences of DATA_READY with 0x100.

   #define SETTINGS(0xE0|0x00|0x00|0x03)

This is a bad macro definition. It defines a macro with a (bad) parameter list, but the parameter list looks more like it should be the definition text. So I suspect this should be:

   #define SETTINGS (0xE0|0x00|0x00|0x03)

Which defines a macro SETTINGS so the preprocessor will replace all occurrences of SETTINGS in the source text with (0xE0|0x00|0x00|0x03).

   #define TRUE 1

   #define FALSE 0

Defines macros TRUE and FALSE so that all occurrences of TRUE will be replaced with 1 and all occurrences of FALSE will be replaced with 0.

OK so how does C++ help us not resort to nasty, dangerous, macros?

Firstly, for the very common case of defining macros for the Boolean values TRUE and FALSE C++ has a bool type that accepts the values true an false. The bool type and the values true and false are part of the C++ language proper [they are keywords (reserved words) in C++]. Hence TRUE and FALSE (and a type alias for BOOL) are not required.

Secondly, C++ differs from C in the way it defines global constant values. In C such a global constant has external linkage (it can be seen from outside the source file it is defined in) by default and therefore has an address allocated to it. In C++ such constant values have internal linkage (local to the source file they are defined in) and a compiler will usually not need to allocate a memory location for such constants (one exception is if the value's address is taken of course). This means we can use constants in C++ with the efficiency of simple #define macros in C, but we get all the proper scope, type safety and contextuality that being a full part of the language affords us. It also means that we can define them in header files (we cannot do this in C because of the one definition rule - if such a definition were to be included in more than one source file then there would be two or more definitions with the same name - which is illegal, and probably will only be picked up by the linker when the many object files defining the same constant are linked together).

So in C++ we can replace:

   #define COM1 0
   #define DATA_READY 0x100
   #define SETTINGS (0xE0|0x00|0x00|0x03)

   unsigned int const Com1(0);
   unsigned int const DataReady(0x100);
   unsigned int const Settings(0xE0|0x00|0x00|0x03);
As these are no longer macros I have changed the naming case rule to one using PascalCase.

In C++ constants, like other objects, have to have an appropriate type. Here I have selected unsigned int, but you might know that the data ready value is used with a byte sized register so maybe it should be:
   unsigned char const DataReady(0x100);
Note we can also say:

   unsigned char const DataReady = 0x100;
   const unsigned char DataReady(0x100);
   const unsigned char DataReady = 0x100;

That is const may be placed before or after the type and we can initialise the constants using either C++ constructor call syntax ( DataReady(0x100) ) or C style initialisation with = syntax (DataReady = 0x100).

Other uses of macros such as writing functions or 'generic' code can be achieved using other C++ facilities e.g.: inlining for small functions, templates for generic code case.

At the end of his book "The Design and Evolution of C++" in chapter 18 Dr. Bjarne Stroustrup lists the following C++ alternatives to uses of preprocessor #define macros:

       - const for constants
       - inline for open subroutines
       - template for functions parameterised by type
       - template for parameterised types
       - namespaces for more general naming

If you would like to know more about how C++ came to be the way it is - and get some insight into the nastiness of the C preprocessor along the way - then reading "The Design and Evolution of C++" might by an idea.

However, despite all effort to date there are still some occasions where macros are required. One idiomatic use is as header file include guards that prevent a header file being included more than one per translation unit (a translation unit is roughly what the compiler proper compiles after preprocessing):

       // contents of header file


The first time the header file is included the header guard macro (named SOME_APPROPIATELY_LONG_AND_UNIQUE_MACRO_NAME in my example) is not defined so the #ifndef (if not defined) conditional code inclusion preprocessor directive condition is true and the code between it and the #endif directive is included in the pre-processed source code. In doing so the header include guard macro is defined. Should the header file be included again the #ifndef condition will no longer be true and the body of the header file will not be included (a second or more time) in the pre-processed source code.

Such guards are required as although you might say you never directly include a header file more than once in your implementation source files how do you know for sure a file is not included more than once without checking the files included by the files you do include and ones they include etc.? In fact it may be impossible to prevent in the general case. That is you can avoid direct repeated inclusion but not indirect repeated inclusion.

Some compilers support a special option (pragma) such as once. #pragma is another preprocessor directive and is used to insert compiler specific options in the source code, so we can use:

   #pragma once

       // contents of header file

Instead of header include guards for headers used with compilers that support such a pragma. However #pragma once is _not_ standard and therefore cannot be relied upon to be supported by all compilers. In fact another compiler could have a subtly different but equivalent facility.

See for more on include guards.

If you really want to know more about the C/C++ preprocessor then you could start with the Wikipedia article at

However C++ has tried to ensure less need to use preprocessor macros . I suggest you approach any such information with the idea of not using the preprocessor macros unless you have to (e.g. no other option, interfacing with C code etc.).


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell


I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.


My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at


©2017 All rights reserved.