SunQuest
 
       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  
Dedicated Servers  
Actuate Whitepapers 
Moblin 
IBM® developerWorks 
Sun Developer Network 
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

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    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

    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion
    - First Steps in (C) Programming, continued
    - First Steps in (C) Programming, introduction
    - C++ Preprocessor: Always Assert Your Code Is...
    - C++ Preprocessor: The Code in the Middle
    - Programming in C
    - Temporary Variables: Runtime rvalue Detection
    - Temporary Variables: Chasing Temporaries Away







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway