tags:

views:

124

answers:

1

Under MSVC 9.0, this fails. Under g++ this compiles. If we take out the macro then the non-macro version 76-79 compiles. Any ideas?

03: #include <iostream>
04: #include <sstream>
67: #define MAKESTRING(msg, v) \
68:        do { \
69:          std::ostringstream s; \
70:          s << msg; \ 
71:          v = s.str(); \
72:        } while(false)
73:        
74:        int main(void)
75:        { 
76:          std::ostringstream oss;
77:          std::string str;
78:          oss << "foo" << "bar";
79:          str = oss.str();
80:        
81:          MAKESTRING("foo" << "bar", str);
82:         }

testenv.cpp(71) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
testenv.cpp(71) : error C2065: 's' : undeclared identifier
testenv.cpp(71) : error C2228: left of '.str' must have class/struct/union
1>        type is ''unknown-type''
testenv.cpp(72) : error C2059: syntax error : '}'
testenv.cpp(72) : error C2143: syntax error : missing ';' before '}'
testenv.cpp(72) : error C2059: syntax error : '}'
testenv.cpp(75) : error C2143: syntax error : missing ';' before '{'
testenv.cpp(75) : error C2447: '{' : missing function header (old-style formal list?)
testenv.cpp(81) : error C2017: illegal escape sequence
testenv.cpp(126) : fatal error C1004: unexpected end-of-file found
+16  A: 

I would make sure that you don't have any trailing whitespace after the backslashes that you use to separate the lines of your macro. Since the compiler is reporting line numbers that are within your macro definition, it means the preprocessor hasn't quite done what you expect.

Also try running this with the MSVC /E compile option to see what the preprocessed source looks like.

Actually, even in the source code you pasted into your question, there is a trailing space on line 70. :)

Greg Hewgill
Nice catch. Guess VC++ is more conforming in that regard.
rlbond
Terrific catch, the error messages could be more helpful
Gregory