0

I have some 3rdparty libraries that are built as part of a large project. Some libraries require C++17, others require features that are removed in C++17 (std::auto_ptr, std::fun_ptr).

For this project, Clang is used (version 11). From searching this mismatch of required versions shouldn't be a problem if I use the clang definition _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES.

However, this has zero effect. I tried this definition in a tiny test sample:

#include <memory>

int main(void)
{
    std::auto_ptr<int> thing(new int(1));
    return 0;
}

Without specifying a C++ std, it compiles fine.

However, if I specify C++17 it fails with -D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES

PS E:\> clang++ -std=c++17 -D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES .\autoptr.cpp
.\autoptr.cpp:5:10: error: no member named 'auto_ptr' in namespace 'std'
    std::auto_ptr<int> thing(new int(1));
    ~~~~~^
.\autoptr.cpp:5:22: error: expected '(' for function-style cast or type construction
    std::auto_ptr<int> thing(new int(1));
                  ~~~^
.\autoptr.cpp:5:24: error: use of undeclared identifier 'thing'
    std::auto_ptr<int> thing(new int(1));
                       ^
3 errors generated.

Are c++17 removed features no longer available in Clang or do I need extra compiler options?

Clang version:

PS E:\> clang++ -v
clang version 11.1.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

edit: Interesting, this compiles fine on a a different system I have. No extra define needed.

#@#:~/kraken$ clang++ -v
clang version 10.0.0-4ubuntu1~18.04.2
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

edit2: Upgraded from 11.1.0 to 12.0.1. No change

$ clang++ -v -stdlib=libc++ -std=c++17 -D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR autoptr.cpp
clang version 12.0.1
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
clang++: warning: argument unused during compilation: '-stdlib=libc++' [-Wunused-command-line-argument]
 "C:\\Program Files\\LLVM\\bin\\clang++.exe" -cc1 -triple x86_64-pc-windows-msvc19.29.30038 -emit-obj -mrelax-all -mincremental-linker-compatible --mrelax-relocations -disable-free -disable-llvm-verifier -discard-value-names -main-file-name autoptr.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -v -resource-dir "C:\\Program Files\\LLVM\\lib\\clang\\12.0.1" -D _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES -D _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR -internal-isystem "C:\\Program Files\\LLVM\\lib\\clang\\12.0.1\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.29.30037\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.29.30037\\atlmfc\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.19041.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.19041.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.19041.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.19041.0\\winrt" -std=c++17 -fdeprecated-macro -fdebug-compilation-dir "E:\\" -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.29.30038 -fdelayed-template-parsing -fcxx-exceptions -fexceptions -faddrsig -o "C:\\Users\\JONATH~1.NOB\\AppData\\Local\\Temp\\autoptr-152d67.o" -x c++ autoptr.cpp
clang -cc1 version 12.0.1 based upon LLVM 12.0.1 default target x86_64-pc-windows-msvc
#include "..." search starts here:
#include <...> search starts here:
 C:\Program Files\LLVM\lib\clang\12.0.1\include
 C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\include
 C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\atlmfc\include
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt
 C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared
 C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um
 C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt
End of search list.
autoptr.cpp:5:10: error: no member named 'auto_ptr' in namespace 'std'
    std::auto_ptr<int> thing(new int(1));
    ~~~~~^
autoptr.cpp:5:22: error: expected '(' for function-style cast or type construction
    std::auto_ptr<int> thing(new int(1));
                  ~~~^
autoptr.cpp:5:24: error: use of undeclared identifier 'thing'
    std::auto_ptr<int> thing(new int(1));
                       ^
3 errors generated.

This output shows the problem. LLVMs libcxx wasn't being used. using -D_HAS_AUTO_PTR_ETC=1 fixes the issue for me.

regomodo
  • 644
  • 3
  • 9
  • 18
  • Seems to behave as expected [here](https://godbolt.org/z/rcsebKn8h) – Jarod42 Sep 09 '21 at 10:13
  • 2
    Honestly, you shouldn't use any libraries that rely on `auto_ptr`... you can certainly find a better opensource library online. – ALX23z Sep 09 '21 at 10:13
  • auto_ptr was already deprecated for C++11. Is the auto_ptr leaking on the third party interface? If not link to the code, do not recompile. Imo fix the real problem, get the 3rd party code updated if you can. (They should have had enough time by now) – Pepijn Kramer Sep 09 '21 at 10:15
  • 2
    When migrating our project to C++17, we got similar issues with library which uses [`std::binary_function`](https://en.cppreference.com/w/cpp/utility/functional/binary_function). Fortunately, we were able to wrap/isolate it as workaround. – Jarod42 Sep 09 '21 at 10:21
  • @Jarod I think what you mean is you created a new static lib, with a new header file in which the deleted types were no longer visible. Compiled that with C++11... and then linked the new library from C++17 right? – Pepijn Kramer Sep 09 '21 at 10:23
  • @PKramer: Yes, (no new headers needed in our case, as the problematic library was just used in cpp). – Jarod42 Sep 09 '21 at 10:28
  • @ALX23z I appreciate your point, but it's a particularly niche, large, library – regomodo Sep 09 '21 at 10:31
  • @Jarod42 I see it uses -stdlib=libc++, I tried that as well to ensure the correct std lib was being used but got a "clang++: warning: argument unused during compilation: '-stdlib=libc++' [-Wunused-command-line-argument]" – regomodo Sep 09 '21 at 10:33
  • 1
    you can define your own `auto_ptr` with `std::unique_ptr` easily. Ugly solution but works. by the way `auto_ptr` was removed c++14 so try `_LIBCPP_ENABLE_CXX14_REMOVED_FEATURES` too – Botond Horváth Sep 09 '21 at 10:35
  • `libstdc++` seems to just have deprecated warning for `autoptr`, not conditional removal [Demo](https://godbolt.org/z/c76MTcWG8). – Jarod42 Sep 09 '21 at 10:36
  • Can you rebuild/modify that 3rd library? – Jarod42 Sep 09 '21 at 10:38
  • @Jarod42 it may unfortunately have to come to that. What's interesting in compiler explorer that the clang compilers there don't need that define to compile successfully. – regomodo Sep 09 '21 at 10:41
  • @BotondHorváth Cheers. no luck here though. Same error. – regomodo Sep 09 '21 at 10:43
  • 1
    Use [_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR](https://libcxx.llvm.org/UsingLibcxx.html) – Hans Passant Sep 09 '21 at 10:54
  • @HansPassant thanks, i had tried that on it's own and with the other define. No change. I starting to think this is a quirk of the compiler version I have as the code compiles fine for me on another clang version – regomodo Sep 09 '21 at 11:00
  • "Deprecated" means **still part of the standard** but might be removed in the future. If your compiler refuses to compile code that uses deprecated features it does not conform to the language definition. – Pete Becker Sep 09 '21 at 14:13
  • 1
    @regomodo: "*require features that are deprecated in C++17 (std::auto_ptr, std::fun_ptr*" They are not 'deprecated' in C++17; they have been *removed* from C++17. "Deprecated" means "available but not advised". – Nicol Bolas Sep 09 '21 at 15:44

1 Answers1

1

Check which c++ stdlib is being used with clang's -v flag. I had assumed the llvm's libcxx was being used as the -stdlib=libcxx was being ignored. In fact, msvc's stdlib was being picked up. With msvc use:

clang++ -std=c++17 -D_HAS_AUTO_PTR_ETC=1 file.cpp
regomodo
  • 644
  • 3
  • 9
  • 18