What is the purpose of llvm::make_unique? - c++

In llvm's compiler implementation tutorial (e.g. here) llvm::make_unique is used. What is the reason they aren't using std::make_unique? I wasn't able to find any clear documentation on this.

TL;DR;
LLVM is written using C++11 conforming code while std::make_unique is a C++14 feature. So if they want make_unique they need to implement it.
Details
If we go to the LLVM Coding Standards the C++ Standard Versions section says:
LLVM, Clang, and LLD are currently written using C++11 conforming code, although we restrict ourselves to features which are available in the major toolchains supported as host compilers. The LLDB project is even more aggressive in the set of host compilers supported and thus uses still more features. Regardless of the supported features, code is expected to (when reasonable) be standard, portable, and modern C++11 code. We avoid unnecessary vendor-specific extensions, etc.
We can see from cppreference that std::make_unique is a C++14 feature. If they want to use make_unique then they can't use the std version.
We can see from a recent llvm-dev discussion that moving to C++14 is still an open subject.

Related

Can't use std::format in c++20

I've been trying to use the std::format function included in C++20. As far as I can tell, clang 14 is supposed to support this feature, but for some reason I am receiving the following error: no member named 'format' in namespace 'std'. According to cppreference's compiler support chart, text formatting should be supported by clang, but I'm still receiving this error. I'm at a loss for what the issue is.
std::format is not complete in libc++ 14 so is disabled by default. You need to pass the LIBCXX_ENABLE_INCOMPLETE_FEATURES parameter when building llvm to enable the feature.
You are probably better off using https://github.com/fmtlib/fmt until the libc++ implementation is complete (this'll also make your code more portable as MSVC is currently the only compiler with a complete implementation).
According to this, text formatting should be supported by clang
If you look closely, there is an asterisk in that cell:
14*
Below, it says:
* - hover over the version number to see notes
And when you hover, it says:
The paper is implemented but still marked as an incomplete feature. Not yet implemented LWG-issues will cause API and ABI breakage.
What's unsaid is that incomplete features are not enabled by default. But that makes sense since they wouldn't want users to depend on an API/ABI that will break. In my opinion, as also evidenced by this question, using green for this cell is misleading.
In conclusion, it's best to use the third party formatting library until the standard implementation of text formatting is complete, stable and non-experimental in major language implementations.
Other caveats:
You must include the header that defines std::format.
Clang doesn't use C++20 by default, so you must specify it explicitly.
Clang uses libstdc++ standard library on Linux by default (for compatibility with shared libraries), so in such case you won't be using the Clang's standard library by default, and libstdc++ hasn't implemented text formatting yet.

Availability of C++11 features

Compiler vendors have been adopting C++11 features piecemeal, which was predictable, as many of them are not easily implemented.
The standard way for reporting which spec the compiler fully supports is via the __cplusplus predefined macro. However, major vendors are reporting __cplusplus = 199711L, meaning they are only fully supporting C++98 (eg. MSVC14). This (presumably) means that they do not fully support the C++11 spec, even though they may have implemented a lion's share of the functionality.
I would like to start using C++11 features, when they are available (and fallback to existing code when they are not). However, my code must support many compilers, including proprietary compilers which I may not have access to use. Is there any standard way to know which C++11 features are available from a compiler, without knowing specifically which compiler is being used? (if a compiler behaves in a non-standard way, then it is acceptable for the detection behavior to be incorrect).
NOTE: This question is a generalization of my question 'Availability of static_assert c++11', which was not very well received, because I think my motivation was misunderstood.
You might be interested in feature test macros, which enable you to test for specific C++11, C++14 or even C++17 features, such as __cpp_static_assert, __cpp_lib_make_unique or __cpp_variable_templates. Clang and GCC already support this, see a live demo.
g++/clang++ do not have C++11 enabled by default, not even the latest versions. Whenever you compile with g++ using -std=c++11, your macro __cplusplus will have the expected value.
VS seem to have all features enabled by default, thanks #Comic, but it is not updating the macro since it is not yet fully C++11 compliant.
As far as detecting "C++11 availability" for a generic compiler, I am not aware of any portable way of doing it, unless you check for the __cplusplus macro. But, as you observed, the macro may not be implemented for some compilers by default (as is the case for g++/clang++), or not implemented at all (VS). Your only choice at this stage seem to be an external tool like CMake, which can detect the compiler, and conditional on the compiler type CMake can then define some macro which you can check in your code to enable C++11.
I think many of the C++11 features are available on GCC 4.8 also. Compile your program with -std=c++11 option.
I think some of the C++11 features were in GCC 4.6.3 as well. Compile option to enable it -std=c++0x .

Why C++11 compiler support still requires a flag?

I understand that experimental features of a programming language should not be enabled by default so I welcome the flags -std=c++0x and -std=c++1y. However C++11 is now standard since a couple of years. Why compilers still require -std=c++11 to enable the support for its features?
C++11 has been standard for a couple of years, but a compiler isn't going to switch its default mode to C++11 until:
At an absolute minimum, C++11 support is complete in that compiler and the libraries it uses. And also stable, if the compiler writer has any concern at all for reliability.
Preferably, a major version number increase in the compiler, since C++11 is not fully backward-compatible to C++03.
Ideally, on a well-known schedule so that users can prepare for the change.
Basically, lots of people (and makefiles) rely on the compiler being a conforming C++03 compiler, or at least on its non-conformance being known. Since C++11 introduces new instances of non-conformance with C++03, the change is potentially traumatic.
Arguably anyone relying on C++03 should have specified an option to say so, and changes to the default mode would make no difference to them. But once you've documented your compiler's default, people are going to rely that, either intentionally or otherwise.
For gcc in particular, the 4.8.2 man page says that "support for C++11 is still experimental". So I think ultimately the answer to your question may be that it takes more than 2 years to properly implement C++11, even starting from all the work done with draft standards.
A small update. GCC 6.1 and above uses a C++14 mode by default [source].

Is C++ 0x/TR1 safe to use when portability matters?

C++03 is lacking some things I'd love to use: std::shared_ptr, std::function and std::bind.
We can't fully switch to C++11, because the project needs to work with older libstdc++ versions. I know that this stuff is in Boost as well, but we cannot use that for other reasons.
Hence we started to use C++ 0x/TR1, which is supported by all the compiler versions we currently use. But we're having some trouble with it:
There's very little information about what of TR1 is implemented in which version of Clang/MSVC/GCC
I cannot figure out what the -std=c++0x switch does in Clang, compiles fine without it
I'm not sure what namespaces to use, e.g. std::tr1::shared_ptr vs std::shared_ptr
So, the question: Is C++ 0x/TR1 safe to use when portability matters? Is it implemented in all major compilers? Should I worry about proprietary toolchains etc.? Are we better off sticking to C++03?
TR1 is an experiment made by the C++ standards committee. The purpose of the experiment is to get field experience for libraries, with the hope of standardizing them in a future standard.
TR1 is not a normative standard.
The spec of TR1 specifies the use of namespace std::tr1. The reason things were not put into namespace std is to allow the committee more freedom in modifying the TR1 specification on the way to standardization. And yes, modifications were made in places when most of TR1 was standardized in C++11.
The TR1 document begins with these words:
This technical report is non-normative. Some of the library components
in this technical report may be considered for standardization in a
future version of C++, but they are not currently part of any C++
standard. Some of the components in this technical report may never be
standardized, and others may be standardized in a substantially
changed form.
The goal of this technical report it to build more widespread existing
practice for an expanded C++ standard library. It gives advice on
extensions to those vendors who wish to provide them.
Most, but not all of TR1, was widely implemented in in the 2005 time frame across gcc and MSVC. The llvm libc++ was developed after the TR1 time frame and was targeted straight at the new C++11 standard, which moves many TR1 components into namespace std, and makes them normative (required by a standard).
Clang is known to be used with both llvm libc++ and gcc's libstdc++.
I do not know which implementations of the std::lib you need to be portable among. If all of the places you need to port to implement TR1, it is safe, otherwise it is not. But TR1 is not a normative standard. C++98, C++03 and C++11 are normative standards.
Checked just for fun, and it turns out libcxx used in Emscripten is
the issue, not Clang 3.2.
I have coached many, many project owners on how to make their code which uses TR1 portable across libstdc++ (has TR1) and libc++ (has C++11). libc++ places those TR1 components that were standardized into C++11 in namespace std as specified in C++11. It does this even when -std=c++03. This was done as a transition aid. libc++ does not try to be a C++03 conforming library. It's life starts with C++11.
libc++ has a version number macro called _LIBCPP_VERSION. If this macro is defined after include'ing a std-header, you are using libc++, else you are not. So you can write code like this:
#ifdef _LIBCPP_VERSION
// using libc++
#include <memory>
typedef std::shared_ptr<MyType> MyTypePtr;
#else // !_LIBCPP_VERSION
// not using libc++
#include <tr1/memory>
typedef std::tr1::shared_ptr<MyType> MyTypePtr;
#endif // _LIBCPP_VERSION
Note that you must have first included some std-header for _LIBCPP_VERSION to get defined or not. If you need to gratuitously include a std-header to see if _LIBCPP_VERSION gets defined, use:
#include <ciso646> // detect std-lib
C++98/03/11 specify <ciso646> to do absolutely nothing. So it is very cheap to include. The libc++ implementation of this header does nothing but define _LIBCPP_VERSION.
Once done, your code can now easily switch among libc++ and other libraries which implement TR1.
Instead of trying to make TR1 work on all your different compilers, I would just take the boost code (header-only) and copy-paste it into your own project (since you can't use boost directly for whatever reason). The boost versions are well supported and debugged, and will work consistently across any C++98 compiler that is supported by boost.

Does clang already support C++11?

I would like to use std::array, std::regex and other things that are new in C++11.
Does clang already support C++11?
Yes but not everything. Check out this status page; it's updated very frequently. It's the current source code (work in progress) state, not the last release state, so check the version in the table to be sure it corresponds to what you have.
For standard library features, checks the links at the end of the page, depending on which context you are in.
Also, the Apache wiki includes this table summarizing C++11 features and their support in popular compilers.
The parts of C++11 that you're looking for are actually part of the standard library. If you're using the clang compiler, you'll want to use the libc++ standard library, which has support for most of C++11 and works really well with clang.