ncurses & stringstream incompatibility

I have a weird problem when including both <curses.h> and <sstream> headers:
1
2
3
4
5
6
7
8
9
// This doesn't compile and I get a lot of errors
#include <curses.h> // only because I included curses before sstream
#include <sstream>

int main()
{
std::stringstream ss;

}

Errors:

In file included from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_pair.h:60,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_algobase.h:66,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/char_traits.h:41,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/ios:41,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/istream:40,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/sstream:39,
from D:\C++\sudas\test\main.cpp:27:
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:56:19: error: macro "move" requires 2 arguments, but only 1 given
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:81:36: error: macro "move" requires 2 arguments, but only 1 given
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:82:30: error: macro "move" requires 2 arguments, but only 1 given
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:83:32: error: macro "move" requires 2 arguments, but only 1 given
In file included from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_algobase.h:66,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/char_traits.h:41,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/ios:41,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/istream:40,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/sstream:39,
from D:\C++\sudas\test\main.cpp:27:
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_pair.h:93:34: error: macro "move" requires 2 arguments, but only 1 given
[...]
files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/ios:41,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/istream:40,
from c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/sstream:39,
from D:\C++\sudas\test\main.cpp:27:
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:56: error: 'std::move' declared as an 'inline' variable
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:56: error: template declaration of 'typename std::remove_reference< <template-parameter-1-1> >::type&& std::move'
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:57: error: expected primary-expression before 'return'
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:57: error: expected '}' before 'return'
c:\program files\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/move.h:59: error: expected declaration before '}' token
Process terminated with status 1 (0 minutes, 1 seconds)
43 errors, 0 warnings





1
2
3
4
5
6
7
8
9
// This compiles ok
#include <sstream>
#include <curses.h>

int main()
{
std::stringstream ss;

}

I can't understand why there are no errors when I include ncurses after sstream header. Also, does this happen with other compilers than GCC-mingw?
The ncurses header probably defined a macro that the sstream header unknowingly uses.
There is a macro in the the curses.h file called move

So when it is this way around:
1
2
3
// This doesn't compile and I get a lot of errors
#include <curses.h> // only because I included curses before sstream
#include <sstream> 


You get the errors because the preprocessor sees this macro first, and then tries to substitute it
in all the following header files - because there is also a move function in the sstream
related headers - this macro substitution will obviously make a nonsense of the sstream related
headers.


When it is this way around:
1
2
3
// This compiles ok
#include <sstream>
#include <curses.h> 

there is no problem ebcause the preprocessor sees the sstream related headers first - and there is no problem.

So the lesson here is if you want to use the curses header and the standard c++ headers - include
the curses header last.
Yes, that's probably what happens. I also want to add that just because including sstream before curses works, this doesn't mean that you should do it. Take a look at these:

This one won't compile:

1
2
3
4
5
6
7
8
9
10
11
12
13
using namespace std;

#define getline(a,b) (cout << "asdf" << endl)

#include <iostream>
#include <string>

int main()
{
    cout << "yo!" << endl;

    return 0;
}

This one compiles ok, but...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace std;

#include <iostream>
#include <string>

#define getline(a,b) (cout << "asdf" << endl)

int main()
{
    cout << "even if this compiles..." << endl;
    cout << "it is dangerous to use!\n" << endl;

    cout << "enter your name: ";
    string name;

    getline(cin,name);

    cout << "hello, " << name << endl;

    return 0;
}

Find another way...
Last edited on
The header file should probably #undef move when it is done with it. Unless it is meant to be available for users... Make a mental note that when writing header files with macros to undefine them when you're done with them (whenever possible).
Last edited on
Ah, right. In that case there should be no problem. But just to be sure, I guess you could do it yourself:

1
2
3
#include <sstream>
#include <curses.h>
#undef move 

EDIT: This would also work:

1
2
3
#include <curses.h>
#undef move
#include <sstream> 
Last edited on
Also there will be problems when using erase() and clear(). I googled a little bit and found that I need to define NCURSES_NOMACROS or NOMACROS before includeing curses:
1
2
3
#define NOMACROS
#include <curses.h>
// ... 

or
1
2
#define NCURSES_NOMACROS
#include <curses.h> 


But this doesn't work for me (probably because I'm using PDCurses)
Last edited on
1
2
3
int     erase(void);
int     clear(void);
int     move(int, int);
These are true functions for me. Maybe you're using an old version?
Damn it! I clicked the big green "Download now" button on sourceforge and it downloaded version 2.4 while the newest version is 3.4...


Topic archived. No new replies allowed.