-
Notifications
You must be signed in to change notification settings - Fork 363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preprocessor failure evaluating BOOST_WORKAROUND #226
Comments
I see, youre testing with Boost. Thats a hell of a C++ project, isnt it ;) I did a while ago too, and I remember this parse failure. Its not a regression. Also, when I remember correctly, its a quite complicated failure, which doesnt happen often. |
Some other boost 1.49 problems below. Keep in mind that 1.49 is still using C++03!
|
On 06/05/2014 03:52 PM, Günter Wirth wrote:
AFAICS, The problem here is that the included filename itself is a
All in all, thats less than I would expect. Last time I played with
|
Some hints from the header file: // Compiler/library version workaround macro
//
// Usage:
//
// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// // workaround for eVC4 and VC6
// ... // workaround code here
// #endif
//
// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the
// first argument must be undefined or expand to a numeric
// value. The above expands to:
//
// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300
//
// When used for workarounds that apply to the latest known version
// and all earlier versions of a compiler, the following convention
// should be observed:
//
// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301))
//
// The version number in this case corresponds to the last version in
// which the workaround was known to have been required. When
// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro
// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates
// the workaround for any version of the compiler. When
// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or
// error will be issued if the compiler version exceeds the argument
// to BOOST_TESTED_AT(). This can be used to locate workarounds which
// may be obsoleted by newer versions.
# define BOOST_WORKAROUND(symbol, test) \
((symbol ## _WORKAROUND_GUARD + 0 == 0) && \
(symbol != 0) && (1 % (( (symbol test) ) + 1)))
// ^ ^ ^ ^
// The extra level of parenthesis nesting above, along with the
// BOOST_OPEN_PAREN indirection below, is required to satisfy the
// broken preprocessor in MWCW 8.3 and earlier.
//
// The basic mechanism works as follows:
// (symbol test) + 1 => if (symbol test) then 2 else 1
// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0
//
// The complication with % is for cooperation with BOOST_TESTED_AT().
// When "test" is BOOST_TESTED_AT(x) and
// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined,
//
// symbol test => if (symbol <= x) then 1 else -1
// (symbol test) + 1 => if (symbol <= x) then 2 else 0
// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero
// Some calling examples: #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550)
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4)) Related defines: #define _MSC_VER 1600
#define BOOST_MSVC _MSC_VER
#define _MSC_VER_WORKAROUND_GUARD 0
#define BOOST_TESTED_AT(value) != ((value)-(value)) |
Call of: #define _MSC_VER_WORKAROUND_GUARD 0
#define _MSC_VER 1600
#define BOOST_MSVC _MSC_VER
... BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_WORKAROUND(symbol, test) \
((symbol ## _WORKAROUND_GUARD + 0 == 0) && \
(symbol != 0) && (1 % (( (symbol test) ) + 1))) results in:
Problem seems to be Reduced test case: #define _MSC_VER_WORKAROUND_GUARD 0
#define _MSC_VER 1600
#define BOOST_MSVC _MSC_VER
#define TEST(symbol) symbol ## _WORKAROUND_GUARD
TEST(BOOST_MSVC); // result should be 0 |
Related to #304? I will test it with that fix. |
Problem is not fixed with #304. In testcase above preprocessor resolves macro in the wrong order: Test in PreprocessorDirectivesTest.java @Test
public void complex_macro_rescanning() {
assert (serialize(p.parse(
"#define _MSC_VER_WORKAROUND_GUARD 0\n"
+ "#define _MSC_VER 1600\n"
+ "#define BOOST_MSVC _MSC_VER\n"
+ "#define TEST(symbol) symbol ## _WORKAROUND_GUARD\n"
+ "TEST(BOOST_MSVC);"))
.equals("0 ; EOF"));
} Preprocessor is a monster :-> I can't fix it. |
During the next days I will try this again (if no one else is working on this currently) |
I do not; I had a quick look, realized that the evaluation of ## is sometimes not at the proper point of time but could not spot a solution. |
Problem is replaceParams/newValue. To get this expandMacro is called which is calling handleIdentifiersAndKeywords again. handleIdentifiersAndKeywords calls again expandMacro. 'The arguments have to be fully expanded before expanding the body of the macro' is wrong. Should expand only one level and calling evaluateHashhashOperators then before doing further expansion. Someone an idea how to fix this? private List<Token> replaceParams(List<Token> body, List<Token> parameters, List<Token> arguments) {
...
// The arguments have to be fully expanded before expanding the body of the macro
String newValue = serialize(expandMacro("", replacement.getValue())); |
Community C++ plugin 0.9.1, getting error message:
Source:
...\Boost\1.49.0\include\boost\detail\workaround.hpp, line 233
The text was updated successfully, but these errors were encountered: