Opened 9 years ago

Closed 7 years ago

Last modified 7 years ago

#8606 closed Bugs (fixed)

Impossible to convert 0-size tuple to (empty) sequence any more

Reported by: vz-boost@… Owned by: No-Maintainer
Milestone: To Be Determined Component: preprocessor
Version: Boost 1.53.0 Severity: Regression
Keywords: Cc:

Description

The following used to work just fine with 1.48:

#include <boost/preprocessor.hpp>

BOOST_PP_TUPLE_TO_SEQ(0, ())

producing

()

on output. With 1.53 (and probably later as there haven't been any changes since then AFAICS) it now also generates the following warnings when using MSVC (tested with 2008 and 2010):

warning C4003: not enough actual parameters for macro 'BOOST_PP_TUPLE_TO_SEQ_1'

but somehow still generates correct output. With g++ 4.4 it's even worse and it expands into

BOOST_PP_TUPLE_TO_SEQ_0 ()

resulting in compilation errors.

This seems to be the result of changes done while adding variadic support to the preprocessor library as BOOST_PP_TUPLE_TO_SEQ_0() definition was removed in this commit.

Notice that the documentation does say that tuple size must be >= 1 but this was changed in 1.49, compare the version above with this one.

Finally notice I decided to open a new ticket for this even though this is already mentioned in a comment in #6616 because the other ticket doesn't to be about the same thing at all, so I thought it would be confusing to continue discussing this issue there. Please feel free to close this one if you think it's really the same issue.

Change History (5)

comment:1 by vz-boost@…, 9 years ago

Summary: Warnings when converting 0-size tuple to sequence with MSVCImpossible to convert 0-size tuple to (empty) sequence any more

After investigating this further, it turns out that doing this with variadic macros is not obvious at all because there doesn't seem to be any way to distinguish between empty tuple and a 1 element tuple as BOOST_PP_VARIADIC_SIZE returns 1 for both of them.

Also, the reason for the difference in behaviour between g++ and MSVC was due to the fact that variadic support is not enabled for Boost Debian package for some reason (the compiler does support variadic macros, of course), so the situation is completely different there, sorry for the confusion.

Anyhow, if there is really no way to handle empty tuples with BOOST_PP_TUPLE_TO_SEQ using variadic macros, could the same functionality be at least provided with non-variadic macros under a different name? It's really useful to handle tuples of all sizes consistently.

comment:2 by Edward Diener, 7 years ago

There is no such thing as a 0 size tuple. The notation of '()' is a tuple whose size is 1 and whose single element is empty. Therefore attempting to convert a zero-sized tuple to any other Boost PP data type, by specifying that the size is 0, is undefined.

comment:3 by Edward Diener, 7 years ago

Resolution: fixed
Status: newclosed

in reply to:  2 comment:4 by vz-boost@…, 7 years ago

Replying to eldiener:

There is no such thing as a 0 size tuple.

Terminological discussions aside, this worked in old Boost versions and was genuinely useful so this is objectively a regression. I know Boost doesn't guarantee backwards compatibility but there is no indication that this breakage was intentional.

comment:5 by Edward Diener, 7 years ago

It is not useful to have a tuple of 0 size and not be able to distinguish between '()' as a tuple of size 0 or a tuple of size 1 with the single element as empty. Since emptiness is perfectly allowable in the preprocessor, and since '(x,)' is clearly a tuple whose size is 2 with the second element being empty, it would always be wrong to make a special case for '()' and declare that this is tuple of size 0. Furthermore treating '()' as a apecial case would make it impossible to have a tuple of size 1 whose single element is empty.

The VC++ preprocessor is a C++ non-standard conforming preprocessor and it is only with heroic effort that Paul Mensonides was able to get VC++ to handle Boost PP processing as much as it does ( there are numerous workarounds in Boost PP code just to handle VC++ ). The gcc preprocessor is vastly closer to the C++ standard.

Note: See TracTickets for help on using tickets.