Opened 10 years ago

Closed 7 years ago

#6989 closed Bugs (fixed)

BOOST_PP_SEQ_ELEM/BOOST_PP_IF behave differently on different compilers

Reported by: vanyacpp@… Owned by: No-Maintainer
Milestone: To Be Determined Component: preprocessor
Version: Boost 1.49.0 Severity: Problem
Keywords: Cc:

Description

MSVC accepts the following code, but gcc reject it with error message that it is impossible to get second element of sequence with size = 1. The problem is that gcc and clang expand both HANDLE_SIZE_EQ_1 and HANDLE_SIZE_EQ_2 before expanding BOOST_PP_IF.

As it turned out MSVC and GCC get different versions of BOOST_PP_SEQ_ELEM. When MSVC get version of BOOST_PP_SEQ_ELEM for GCC it also show warning.

See connect.microsoft.com/VisualStudio/feedback/details/743894/possibly-incorrect-macro-expansion-order for details.

boost version 1.49 #include <boost/preprocessor/comparison/not_equal.hpp> #include <boost/preprocessor/seq/cat.hpp> #include <boost/preprocessor/seq/elem.hpp> #include <boost/preprocessor/seq/size.hpp>

#define HANDLE_SIZE_EQ_1(seq)

#define HANDLE_SIZE_EQ_2(seq) \

BOOST_PP_SEQ_ELEM(1, seq)

#define TEST_IF(seq) \

BOOST_PP_IF(BOOST_PP_NOT_EQUAL(2, BOOST_PP_SEQ_SIZE(seq)) \ , HANDLE_SIZE_EQ_1(seq) \ , HANDLE_SIZE_EQ_2(seq))

TEST_IF((a))

Change History (2)

comment:1 by Edward Diener, 7 years ago

Gcc is correct and MSVC is wrong. The proper way to write such code is:

#define HANDLE_SIZE_EQ_1(seq)

#define HANDLE_SIZE_EQ_2(seq) \
    BOOST_PP_SEQ_ELEM(1, seq)

#define TEST_IF(seq) \
    BOOST_PP_IF(BOOST_PP_NOT_EQUAL(2, BOOST_PP_SEQ_SIZE(seq)), \
    HANDLE_SIZE_EQ_1, \
    HANDLE_SIZE_EQ_2) \
    (seq)

TEST_IF((a))

The code will work on VC++ and gcc. This is not a bug in the preprocessor but in your code.

comment:2 by Edward Diener, 7 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.