Subject: toolchain/20421: gcc -isystem flag with C++ breaks templates in system paths (especially STL)
To: None <>
From: None <>
List: netbsd-bugs
Date: 02/18/2003 20:11:14
>Number:         20421
>Category:       toolchain
>Synopsis:       gcc -isystem flag with C++ breaks templates in system paths (especially STL)
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 18 20:12:00 PST 2003
>Originator:     Andrew White
>Release:        1.6
Motorola Australian Research Centre
NetBSD 1.5.2 NetBSD 1.5.2 (ARTHUR_RAID) #1: Mon Jul 22 18:06:13 EST 2002
When compiling C++ code, using -isystem appears to implicitly 'extern "C"' any system header files.  As a result, any templates in these files fail with a 'template with C linkage' error.  This renders the entire STL useless.

This seems to be a known bug with some distributions of the GCC 2.95 compiler - see report #7327.

This problem is serious because the NetBSD build tool builds C++ as follows:     ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c   ${DESTDIR:D-nostdinc ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include}   ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include/g++}     -isystem     -idirafter  ${DESTDIR:D-nostdinc ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include}  ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include/g++}

Thus, all C++ code built using into the NetBSD system will be built with -nostdinc++ -isystem (path) -nostdinc -isystem (path), invoking the error if it uses the STL.
In C++ program on 1.6 system:

#include <hash_map>
  // or any other STL header

Compile using

gcc -nostdinc++ -isystem /usr/include/g++ ...

Compiler will descend into STL headers before failing with 'template with C linkage' on each template found.
Attempted workaround by replacing -isystem (and -idirafter) with -I.  Problem is that -isystem seems to search recursively, so including

  -nostdinc -isystem /usr/include/

will trigger the same behaviour, even though relevant headers are in /usr/include/g++.  When building NetBSD from source, both -nostdinc and -nostdinc++ are included.

Replacing all instances of -isystem and -idirafter with -I works as a workaround.  However, see below.

Editing CPPFLAG_ISYSTEM = -I in will cause all code (C and C++) to be built with -I rather than -isystem, which is probably not desired.

Correct fix is to disable implicit 'extern' on -isystem.