C++
  Home arrow C++ arrow Page 3 - C++ Preprocessor: The Code in the Middle
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

C++ Preprocessor: The Code in the Middle
By: J. Nakamura
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 36
    2005-10-31

    Table of Contents:
  • C++ Preprocessor: The Code in the Middle
  • String Substitution
  • String Manipulation
  • Conditional Compilation
  • Inclusion Guards
  • Predefined Macros

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    C++ Preprocessor: The Code in the Middle - String Manipulation


    (Page 3 of 6 )

    When you use the preprocessor for string substitution it can do more than simply replace tokens with values. It is possible to quote strings that were passed as a parameter and you can concatenate two strings together into one.

    The stringizing operator (#) substitutes the macro variable following it with its value and puts quotes around it.

    For example:

    #define LOG(x) std::cout << #x << std::endl

    When used like:

    LOG(Hello World);

    will be substituted into and presented to the compiler as:

    std::cout << “Hello World” << std::endl;

    With the concatenation operator (##) you can tie separate strings into a new single identifier. There are many useful things you can do with this and we’ll actually need this operator when we implement customizable streams.

    It is also possible to drive things to extremes. There is a company I know of that requires in its coding standard that you use their ‘Simplified Hungarian naming convention’. This means that a function that takes a const reference to an object MyClass doesn’t look like:

    void foo ( MyClass const &obj );

    But in their code looks like:

    void foo ( rcMyClass obj );

    While this might save you some typing effort, I wouldn’t recommend making such drastic changes to the C++ language. Still as an example… how did it ever get this far?

    #define DECLARE_HUNGARIAN( cls ) typedef cls const & rc##cls; \
           typedef cls *       p##cls;

    Now you’ve made the following code possible:

    DECLARE_HUNGARIAN( MyClass )
    pMyObject bar();

    Macro Functions

    The ‘#define’ directive is very versatile and powerful, given the simple fact that it can replace one string with another string: we can create macro functions.

    #define SQUARE(x) ( (x) * (x) )

    The MIN and MAX macros are also often quoted as examples:

    #define MIN(x,y) ( (x) < (y) ? (x) : (y) )
    #define MAX(x,y) ( (x) > (y) ? (x) : (y) )

    You have to remember that all this does is string substitution, and any form of type checking is completely lacking!

    An important note is that the opening parenthesis for the parameter list must immediately follow the macro name. There are no spaces allowed, since the preprocessor will otherwise consider it to be a regular string substitution.

    In case you wonder why the parameters are all wrapped in parenthesis again, consider what would happen if we’d defined SQUARE as:

    #define SQUARE(x) ( x * x )

    Now why does the following give a result of 11 instead of 25?

    int n = SQUARE( 2 + 3 );

    Ouch this is not what we intended:

    int n = 2 + 3 * 2 + 3;

    But using parenthesis it is correct again:

    int n = (2 + 3) * (2 + 3)

    More C++ Articles
    More By J. Nakamura


       · Hi, C++ coders. Thanks for reading Dev Articles. Please let us know what you think...
     

    C++ ARTICLES

    - More Tricks to Gain Speed in Programming Con...
    - Easy and Efficient Programming for Contests
    - Preparing For Programming Contests
    - Programming Contests: Why Bother?
    - Polymorphism in C++
    - Overview of Virtual Functions
    - Inheritance in C++
    - Extending the Basic Streams in C++
    - Using Stringstreams in C++
    - Custom Stream Manipulation in C++
    - General Stream Manipulation in C++
    - Serialize Your Class into Streams in C++
    - Advanced File Handling with Streams in C++
    - File Handling and Streams in C++
    - The STL String Class







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    Stay green...Green IT