28

This is the first time I use clang. What I notices is that any error from clang referencing the std library looks like this:

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:245:7:
                ^^^                  ^^^                         ^^^

So it looks like clang links — or at least includes — the gcc libraries.

The command I used: clang++ -c -Wall -Wextra -Werror -g test.cpp -o test.o. (The program had a intentional error just to prove this).

How is this possible? What can I do to make clang use its own libraries (but not break gcc)?


Additional information:

I am on a Ubuntu 14.04 machine.

clang++ --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix

g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.

I had previously installed several versions (at the same time, used them with update-alternatives) of gcc with apt-get. Right now I have only 4.8 (I have uninstalled the others). Could I have messed up something then? I have never installed clang (I guess it is default with Ubuntu).

Just to clarify: the correct programs compile and run in clang++.

Further tests: I know that gcc didn’t implement yet types like is_trivially_constructible and move operations on iostream in their standard c++11 library (https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html) and that clang has full c++11 conforming library so I tested those compiling with clang and I got the corresponding gcc errors, which only confirms that clang is using gcc libraries.

A very basic program

#include <iostream>
using namespace std;

int main() { 
  cout << "Yada Yada" << endl;
  return 0;
}

gives this error when compiling with -std=c++1y in clang++:

In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/iostream:39:
...
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:120:11: error: no member named 'gets' in the global namespace
  using ::gets;
        ~~^

So right now I can’t compile anything with c++1y in clang.

bolov
  • 72,283
  • 15
  • 145
  • 224

3 Answers3

28

You need to install libc++ and make clang use it with -stdlib=libc++

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • I couldn’t install `libc++` (some errors about dependencies). I installed `libc++1` (which looks like it's the c++11 library which is what I want). When I compile with `-stdlib=libc++` I get `fatal error: 'iostream' file not found #include `. If I compile with `-stdlib=libc++1` I get `clang: error: invalid library name in argument '-stdlib=libc++1'`. Any idea? Thank you. – bolov Jun 21 '14 at 14:21
  • as per this answer http://stackoverflow.com/questions/20587228/clang-error-stddef-file-not-found I have checked both simlinks and they are both correct, but in the folders linked there are a few headers, but not standard headers – bolov Jun 21 '14 at 14:36
  • I'm sorry, I don't no much about Ubuntu, but under Fedora it was easy to build libc++ from source. (Although I got a funny linker error, but that is a different question and already answered on SE). – Baum mit Augen Jun 21 '14 at 18:46
  • 6
    @bolov To actually build new programs with it, you need `libc++-dev` (the headers), not just `libc++1` (the library). – o11c Jan 30 '15 at 06:06
  • @o11c, if I compile a binary to give to others, will I need to ensure that the users have `libc++1` on their machine? Although, I guess the same question applies to `g++` and `libstdc++`. Do modern Linux distributions install some version of `libstdc++` by default? – Aaron McDaid Jul 14 '15 at 10:43
  • @AaronMcDaid *"Do modern Linux distributions install some version of libstdc++ by default?"* No they don't. You can in general not just ship binaries for Linux. See e.g. http://stackoverflow.com/questions/7461152/is-it-possible-to-compile-a-c-c-source-code-that-executes-in-all-linux-distrib – Baum mit Augen Jul 14 '15 at 15:28
  • @AaronMcDaid LSB requires some version of `libstdc++.so.6`, but then you have to worry about which *version* of LSB supports which *version* of `libstdc++.so.6` – o11c Jul 14 '15 at 18:59
12

I had similar issue: GCC (g++) already was installed on my LinuxMint (Ubuntu base) so when compile with clang, was getting an " error: no member named 'gets' in the global namespace using ::gets ".

resolved by installing libc++-dev (sudo apt-get install libc++-dev) and compiling with -stdlib++ (clang++ -g -std=c++1y -stdlib=libc++ helloworld.cpp -o helloworld)

Michael Haidl
  • 5,384
  • 25
  • 43
Rolis
  • 121
  • 1
  • 4
8

Your real problem is that you're using C++14 (c++1y was the informal name used to refer to it when it wasn't yet fully formed), with a C++ library belonging to GCC 4.8. GCC 4.8 has complete C++11 support, but hardly even started on C++14 features.

This is caused by C++14 removing std::gets, and the GNU C library anticipating on that by not defining gets in the global namespace while the C++ library has not yet caught up and is trying to make it available in the std namespace.

The proper way to solve this does not require using libc++, just to use a C++ library with C++14 support. GLIBCXX 4.9 (aka libstdc++) already suffices.

Giel
  • 2,787
  • 2
  • 20
  • 25
  • this is not the real problem. I knew that `libstd++` and `libc++` differ in the stage of implementation for C++11/C++14 standard and I merely used this knowledge to prove which library was used. – bolov Jan 12 '18 at 15:17
  • I got this exact error message with the same GCC version (4.8.2) when attempting to build in C++14 mode with Clang 3.8, using GCC 4.9.4's libstdc++ fixes it. – Giel Jan 12 '18 at 17:43
  • again: this question is not about fixing the errors. Read the paragraph starting with "Further tests" from my question. – bolov Jan 12 '18 at 19:44