问题
I am porting some code to OpenBSD 5.0 and I ran into this very strange problem.
My build settings use -isystem /usr/local/include
. It is hard to remember but I believe I did that to avoid masses of compiler warnings from my use of -Wall
on system types -- like BSD -- that install Boost to /usr/local/include
. This seems to work great on FreeBSD.
So take the following program:
#include <boost/array.hpp>
int main()
{
return 0;
}
Then build it with:
c++ -O2 -pipe -isystem /usr/local/include -std=c++98 -o test test.cxx
On OpenBSD I discovered that I get:
In file included from /usr/include/g++/string:46,
from /usr/include/g++/stdexcept:44,
from /usr/local/include/boost/array.hpp:35,
from test.cxx:1:
/usr/include/g++/bits/stringfwd.h:48: error: template with C linkage
And it only gets worse from there.
I discovered that I can change the error messages by doing things such as:
#include <stdexcept>
But that only pushes the problem farther back. It is as if the compiler is wrapping every include file inside an extern "C"
block.
So far, the only working method seems to be to change back to using -I /usr/local/include
and accept the noise from -Wall -W
.
The question is, why did OpenBSD do this? It has to be some kind of custom hack to GCC to treat system includes this way.
回答1:
Recently came across the same issue when working with a freestanding cross compiler.
It seems G++ will do this when targeting "old" systems as indicated here:
http://tigcc.ticalc.org/doc/cpp.html#SEC9a
On very old systems, some of the pre-defined system header directories get even more special treatment. GNU C++ considers code in headers found in those directories to be surrounded by an extern "C" block. There is no way to request this behavior with a #pragma, or from the command line.
Hope this may provide some insight to future travelers here.
来源:https://stackoverflow.com/questions/9775583/why-does-openbsds-g-make-system-headers-default-to-c-linkage