[Boost-bugs] [Boost C++ Libraries] #4501: BOOST_PP_SEQ_FOR_EACH fails in corner case

Subject: [Boost-bugs] [Boost C++ Libraries] #4501: BOOST_PP_SEQ_FOR_EACH fails in corner case
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-08-01 19:40:32


#4501: BOOST_PP_SEQ_FOR_EACH fails in corner case
----------------------------+-----------------------------------------------
 Reporter: ookami1@… | Owner: no-maintainer
     Type: Bugs | Status: new
Milestone: Boost 1.44.0 | Component: preprocessor
  Version: Boost 1.44.0 | Severity: Problem
 Keywords: |
----------------------------+-----------------------------------------------
 Hi,

 BOOST_PP_SEQ_FOR_EACH fails when submitted a sequence of maximum length.
 The following program demonstrates this. It runs a loop over one sequence
 of 255 elements and one of 256 elements, generating empty expansions for
 each element. Thus, the expansions should be empty each. The output shows,
 that variable x255 contains the expected result, while the contents of
 x256 indicate an internal error.


 {{{
 #include <cstdio>
 #include <boost/preprocessor.hpp>
 #define SEQ_255 \
         (1)(2)(3)(4)(5)(6)(7)(8)(9) \
         (10)(11)(12)(13)(14)(15)(16)(17)(18)(19) \
         (20)(21)(22)(23)(24)(25)(26)(27)(28)(29) \
         (30)(31)(32)(33)(34)(35)(36)(37)(38)(39) \
         (40)(41)(42)(43)(44)(45)(46)(47)(48)(49) \
         (50)(51)(52)(53)(54)(55)(56)(57)(58)(59) \
         (60)(61)(62)(63)(64)(65)(66)(67)(68)(69) \
         (70)(71)(72)(73)(74)(75)(76)(77)(78)(79) \
         (80)(81)(82)(83)(84)(85)(86)(87)(88)(89) \
         (90)(91)(92)(93)(94)(95)(96)(97)(98)(99) \
         (100)(101)(102)(103)(104)(105)(106)(107)(108)(109) \
         (110)(111)(112)(113)(114)(115)(116)(117)(118)(119) \
         (120)(121)(122)(123)(124)(125)(126)(127)(128)(129) \
         (130)(131)(132)(133)(134)(135)(136)(137)(138)(139) \
         (140)(141)(142)(143)(144)(145)(146)(147)(148)(149) \
         (150)(151)(152)(153)(154)(155)(156)(157)(158)(159) \
         (160)(161)(162)(163)(164)(165)(166)(167)(168)(169) \
         (170)(171)(172)(173)(174)(175)(176)(177)(178)(179) \
         (180)(181)(182)(183)(184)(185)(186)(187)(188)(189) \
         (190)(191)(192)(193)(194)(195)(196)(197)(198)(199) \
         (200)(201)(202)(203)(204)(205)(206)(207)(208)(209) \
         (210)(211)(212)(213)(214)(215)(216)(217)(218)(219) \
         (220)(221)(222)(223)(224)(225)(226)(227)(228)(229) \
         (230)(231)(232)(233)(234)(235)(236)(237)(238)(239) \
         (240)(241)(242)(243)(244)(245)(246)(247)(248)(249) \
         (250)(251)(252)(253)(254)(255)
 #define SEQ_256 SEQ_255(256)

 #define M(r, data, elem)

 char const x255[] = BOOST_PP_STRINGIZE(BOOST_PP_SEQ_FOR_EACH(M,
 BOOST_PP_NIL, SEQ_255));
 char const x256[] = BOOST_PP_STRINGIZE(BOOST_PP_SEQ_FOR_EACH(M,
 BOOST_PP_NIL, SEQ_256));

 int main()
 {
         printf("255: %s\n", x255);
         printf("256: %s\n", x256);
 }


 }}}


 Output of the program:


 {{{
 255:
 256:
 BOOST_PP_IIF_BOOST_PP_BOOL_BOOST_PP_DEC_BOOST_PP_SEQ_SIZE_BOOST_PP_SEQ_SIZE_257(BOOST_PP_SEQ_FOR_EACH_M
 (...rest omitted)
 }}}


 The occurrence of BOOST_PP_SEQ_SIZE_257 in the output indicates, that
 during expansion BOOST_PP_SEQ_SIZE has overflown.

 Indeed, the expansion of BOOST_PP_SEQ_FOR_EACH pads a (nil) element to the
 right of the input sequence, which later will cause the overflow of
 BOOST_PP_SEQ_SIZE. IMO there is, unfortunately, another, more serous
 limitation, that will prevent successful expansion of the macro, even
 after the size problem has been solved. It is related to BOOST_PP_FOR, on
 which BOOST_PP_SEQ_FOR_EACH is based.

 Macros cannot be called recurively, hence, all loops have to be unrolled.
 BOOST_PP_FOR in repetition/for.hpp, provides 256 slots for loops, one
 needed to exit the loop. This leaves 255 slots free for iterating - one
 missing for maximum sized sequences. Because of this, I suspect
 beforehand, more macros based on BOOST_PP_FOR will fail when fed with
 border case parameters.

 Regards

 Wolf Lammen

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/4501>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:04 UTC