Boost C++ Libraries: Ticket #4501: BOOST_PP_SEQ_FOR_EACH fails in corner case https://svn.boost.org/trac10/ticket/4501 <p> Hi, </p> <p> 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. </p> <pre class="wiki">#include &lt;cstdio&gt; #include &lt;boost/preprocessor.hpp&gt; #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); } </pre><p> Output of the program: </p> <pre class="wiki">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) </pre><p> The occurrence of BOOST_PP_SEQ_SIZE_257 in the output indicates, that during expansion BOOST_PP_SEQ_SIZE has overflown. </p> <p> 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. </p> <p> 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. </p> <p> Regards </p> <p> Wolf Lammen </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4501 Trac 1.4.3 Edward Diener Sun, 17 May 2015 18:02:35 GMT <link>https://svn.boost.org/trac10/ticket/4501#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:1</guid> <description> <p> I am not seeing this example failing in the latest version of Boost, which is Boost 1.58. I do see a failure in VC++ stating: </p> <p> fatal error C1009: compiler limit : macros nested too deeply </p> <p> but that is a compiler problem which Boost PP cannot solve. </p> <p> Your test passes with gcc and clang. </p> </description> <category>Ticket</category> </item> <item> <author>ookami1@…</author> <pubDate>Sun, 17 May 2015 21:18:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4501#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:2</guid> <description> <p> I am afraid the problem persists. Boost 1.58 is affected. See my comments in bug report <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4523" title="#4523: Patches: fix for #4501 (closed: fixed)">#4523</a>. </p> <p> Cheers Wolf </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/4501#comment:1" title="Comment 1">eldiener</a>: </p> <blockquote class="citation"> <p> I am not seeing this example failing in the latest version of Boost, which is Boost 1.58. I do see a failure in VC++ stating: </p> <p> fatal error C1009: compiler limit : macros nested too deeply </p> <p> but that is a compiler problem which Boost PP cannot solve. </p> <p> Your test passes with gcc and clang. </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Edward Diener</dc:creator> <pubDate>Mon, 18 May 2015 06:17:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4501#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:3</guid> <description> <p> I have fixed this on the latest 'develop' branch of Boost PP. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Edward Diener</dc:creator> <pubDate>Tue, 19 May 2015 15:41:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4501#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:4</guid> <description> <p> I have had to back out this change in 'develop' because of a problem encountered. I will be working on another fix for this problem. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Edward Diener</dc:creator> <pubDate>Wed, 20 May 2015 00:14:50 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4501#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:5</guid> <description> <p> I have corrected the fix for this bug and it is now on the 'develop' branch. The previous fix was not wrong itself but led to potential warnings from various compilers in C++03 mode. The corrected fix avoids any warnings in any C++ mode. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Edward Diener</dc:creator> <pubDate>Fri, 21 Aug 2015 13:52:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4501#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4501#comment:6</guid> <description> <p> This has now been fixed in the latest Boost 1.59 release. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Edward Diener</dc:creator> <pubDate>Fri, 21 Aug 2015 13:52:57 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/4501#comment:7 https://svn.boost.org/trac10/ticket/4501#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket