CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jan 2004
    Posts
    13

    Preprocessor tricks

    Let's suppose that we have defined following macros:
    Code:
    #define AAA 'a'
    #define BBB 8
    Is it possible somehow to define a macro CCC which will be the string of AAA duplicated BBB times?

    Code:
    #define CCC "aaaaaaaa"
    I'm loooking the equivalent to above mentioned CCC macro definition, which
    will be changed automatically whenever AAA or BBB is changed.
    CCC should be constructed from AAA and BBB in compile-time.

    Thank You.

  2. #2
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Preprocessor tricks

    No, that's not how preprocessor works. Preprocess is done at essentially copy and paste, you can't have logic like that.

  3. #3
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Preprocessor tricks

    It's trivial to implement, albeit the code can become quite bulky (if done in a reusable manner).
    Luckily, most of the legwork has been written for you already (see the Boost.Preprocessor library):
    Code:
    #define AAA "a"
    #define BBB 8
    #define REPEAT_VERBATIM(z, n, aux) aux
    #define CCC BOOST_PP_REPEAT(BBB, REPEAT_VERBATIM, AAA)
    CCC should effectively expand to "a" * BBB. During compilation, these adjacent strings will be concatenated and you'll end up with what you asked for in your OP.

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Preprocessor tricks

    Preprocessor tricks might just be the one thing less intuitive than template metaprogramming.

  5. #5
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Preprocessor tricks

    CCC should effectively expand to "a" * BBB. During compilation, these adjacent strings will be concatenated and you'll end up with what you asked for in your OP.
    It won't work. Preprocessing is done in single phase, not in two phases.
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  6. #6
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Preprocessor tricks

    Quote Originally Posted by Ajay Vijay View Post
    It won't work.
    Yes, it will.

    Quote Originally Posted by Ajay Vijay View Post
    Preprocessing is done in single phase, not in two phases.
    You clearly don't understand how BOOST_PP_REPEAT works, then.

  7. #7
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Preprocessor tricks

    You clearly don't understand how BOOST_PP_REPEAT works, then.
    Actually I did not. And I still couldn't understand how it works. But I see this macro is using templates.
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  8. #8
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Preprocessor tricks

    Quote Originally Posted by Ajay Vijay View Post
    But I see this macro is using templates.
    What templates?

    Quote Originally Posted by Ajay Vijay View Post
    And I still couldn't understand how it works.
    Simulated recursion.

    Quite easily generated:
    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    foreach(2 .. $ARGV[0])
    {
      my $i = $_ - 1;
    
      print "#define REPEAT_$_(m, d) REPEAT_$i(m, d)m($i, d)\n";
    }
    Code:
    #define EXPAND_CONCAT(a, b) a##b
    #define REPEAT(n, m, d) EXPAND_CONCAT(REPEAT_, n)(m, d)
    
    #define REPEAT_0(m, d)
    #define REPEAT_1(m, d) m(0, d)
    #define REPEAT_2(m, d) REPEAT_1(m, d)m(1, d)
    #define REPEAT_3(m, d) REPEAT_2(m, d)m(2, d)
    #define REPEAT_4(m, d) REPEAT_3(m, d)m(3, d)
    #define REPEAT_5(m, d) REPEAT_4(m, d)m(4, d)
    #define REPEAT_6(m, d) REPEAT_5(m, d)m(5, d)
    #define REPEAT_7(m, d) REPEAT_6(m, d)m(6, d)
    #define REPEAT_8(m, d) REPEAT_7(m, d)m(7, d)
    #define REPEAT_9(m, d) REPEAT_8(m, d)m(8, d)
    //...
    //#define REPEAT_{LIM}(m, d) REPEAT_{LIM-1}(m, d)m({LIM-1}, d)
    This particular implementation can be affected by your preprocessor's recursive depth limitations.
    You can work around this limitation by expanding each REPEAT_N call yourself (i.e., while generating the chain), at the expense of your source file's size, of course.

    That said, considering the OP's original requirements:
    Code:
    #define ELEM "a"
    #define COUNT 8
    #define REPEAT_VERBATIM(i, d) d
    #define EXPRESSION REPEAT(COUNT, REPEAT_VERBATIM, ELEM)
    1. EXPRESSION will expand to "a""a""a""a""a""a""a""a" in translation phase 4.
    2. "a""a""a""a""a""a""a""a" will be converted to "aaaaaaaa" in translation phase 6.

    Not confusing at all.
    Last edited by Plasmator; October 8th, 2009 at 11:30 AM. Reason: Typo.

  9. #9
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Preprocessor tricks

    Quote Originally Posted by Lindley View Post
    Preprocessor tricks might just be the one thing less intuitive than template metaprogramming.
    LOL
    Both are great techniques for stopping a maintenance programmer in his tracks.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured