42

I have a project that correctly compiles and runs under g++ 4.8.1 and clang >= 3.3 in c++11 mode. However, when I switch to the experimental -std=c++1y mode, clang 3.3 (but not g++) chokes on the <cstdio> header that is indirectly included by way of Boost.Test (so I cannot easily change it myself)

// /usr/include/c++/4.8/cstdio
#include <stdio.h>

// Get rid of those macros defined in <stdio.h> in lieu of real functions.
// ...
#undef gets
// ...    

namespace std
{
// ...
using ::gets; // <-- error with clang++ -std=c++1y
// ...
}

with the following error message:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:119:11: error: no member named 'gets' in the global namespace

On this tutorial on how to set up a modern C++ environment, a similar lookup problem with max_align_t is encountered. The recommendation there is to use a sed script to surround the unknown symbols with #ifdef __clang__ macros, but that seems a fragile approach.

Setup: plain 64-bit Linux Mint 15 with

g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1

Ubuntu clang version 3.3-3~raring1 (branches/release_33) (based on LLVM 3.3)

Questions:

  • what is causing this erorr? There is no __clang__ macro anywhere near the code in question, and clang in c++11 mode has no trouble at all.
  • Is it a language problem (does C++14 say something else than C++11 about importing C compatible symbols from the global into the std namespace)?
  • Do I need to change something with my include paths? (I use CMake to automatically select the header paths, and switch modes inside CMakeLists.txt)
  • Does clang have a switch to resolve this?
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • It looks like you have a broken `stdio.h`. Perhaps reinstall the package that contains such standard header files? – Ben Voigt Jul 21 '13 at 20:23
  • ooo, it's not broken, it's been updated to C11. – Ben Voigt Jul 21 '13 at 20:27
  • 1
    Also see [LLVM Issue 30277: Clang 3.6 cannot compile program with -std=c++14](https://llvm.org/bugs/show_bug.cgi?id=30277) and [Ubuntu Issue 1620181: Clang 3.6 cannot compile program with -std=c++14](https://bugs.launchpad.net/ubuntu/+bug/1620181) on Launchpad. – jww Sep 05 '16 at 04:53
  • 1
    Also see section ***C.3.4 - Removal of std::gets*** at [What changes introduced in C++14 can potentially break a program written in C++11?](http://stackoverflow.com/a/23980931/608639) – jww Sep 07 '16 at 03:38

1 Answers1

23

This note in the gets manpage looks relevant:

ISO C11 removes the specification of gets() from the C language, and since version 2.16, glibc header files don't expose the function declaration if the _ISOC11_SOURCE feature test macro is defined.

Probably should be

#if !_ISOC11_SOURCE
using ::gets;
#endif
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Or test if __cplusplus is strictly more than that of C++11, since glibc assumes that gets won't be in C++14 (not clear yet). – Marc Glisse Jul 21 '13 at 21:01
  • @MarcGlisse do you know if there is any version of glibc that has such a macro test already? I'm asking because this [live example](http://coliru.stacked-crooked.com/view?id=776bf23db41af3414d2e28f342ef65da-5e316e07ec27fc464f163e0f41ec1258) works fine, and even though I have the same clang version, I do get an error, so I'm guessing my headers are messed up somehow. – TemplateRex Jul 22 '13 at 06:35
  • I think the simplest way is to *downgrade* glibc to 2.15 (Linux Mint 15 comes with 2.17), which could also explain why the Coliru site has not problems as it is based on Ubuntu 12.04LTS, which has 2.15 – TemplateRex Jul 22 '13 at 06:43
  • 3
    Yes there is, did you check your `stdio.h`? 2.17 has `#if !defined __USE_ISOC11 || (defined __cplusplus && __cplusplus <= 201103L)`. – Marc Glisse Jul 22 '13 at 08:10
  • @MarcGlisse yes, my `stdio.h` indeed had that. But unless `cstdio` also gets such a macro, it won't build under `clang++ -std=c++1y`. I simply downgraded the glibc to 2.15 and now it works. – TemplateRex Jul 22 '13 at 20:27
  • 1
    `cstdio` from libstdc++ tests `#if __cplusplus <= 201103L` in gcc-4.9 (can't easily check 4.8 right now). – Marc Glisse Jul 22 '13 at 22:42
  • 2
    See http://sourceware.org/bugzilla/show_bug.cgi?id=13566 and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51785 for some of the history – Jonathan Wakely Jul 24 '13 at 14:42
  • 2
    @JonathanWakely Thanks for the links. So the two acceptable solutions are that either glibc and libstdc++ both have a `#ifdef` around `gets`, or they both unconditionally declare it. Is there any chance of backporting the 4.9 fix to 4.8? – TemplateRex Jul 26 '13 at 06:50
  • @JonathanWakely not sure if you coordinate at all with libc++, but FYI, [a similar thread on the Clang mailinglist](http://clang-developers.42468.n3.nabble.com/libc-gets-removed-from-C11-td4032945.html) – TemplateRex Aug 05 '13 at 19:41
  • Also see [LLVM Issue 30277: Clang 3.6 cannot compile program with -std=c++14](https://llvm.org/bugs/show_bug.cgi?id=30277) and [Ubuntu Issue 1620181: Clang 3.6 cannot compile program with -std=c++14](https://bugs.launchpad.net/ubuntu/+bug/1620181) on Launchpad. – jww Sep 05 '16 at 04:55
  • Also see section ***C.3.4 - Removal of std::gets*** at [What changes introduced in C++14 can potentially break a program written in C++11?](http://stackoverflow.com/a/23980931/608639) – jww Sep 07 '16 at 03:38