Will I be able to `import <standard_headers>`? - c++

Multiple talks have taught me that we can import <standardheaders>, but this does not seem to work at all in Compiler Explorer. In latest Clang and GCC, I just get errors, and when googling for this, I see some Microsoft documents that say it's doable, but they seem very non-standard in their approach, regrouping the headers in some vendor-specific way.
What gives?
Will we be able to do this? or it is never gonna happen in a standard way? Is it dependent on a build system doing it for us individually even though they are standard headers? Was this a planned feature that was dropped? Or was it always planned to be highly vendor specific and non-standardized, and to require a build system even for standard headers? Is there a plan to standardize at least the division of standard features so that we don't have a bunch of different vendor specific organization schemes that are different than the header scheme?

The proposal to make standard headers importable as synthesized header units is P1502.
STL says in MSVC's issue that it is feature complete for VS 2019 16.10 Preview 2.
Neither GCC documentation nor Clang documentation list their current status for P1502, but support for modules in general is "partial".
Will we be able to do this?
Presumably when the compiler / standard library implementers get to it. Until then, we can safely use #include which doesn't have drawbacks compared to synthesized header units.

Related

Is there a reason not to use the newest C++ standard?

I have seen that the default standard in IDEs is usually not the newest released standard, not even the newest standard in the IDE.
For example JetBrains' Clion has C++20 and C++17 but the default option is C++14.
Is there a reason not to use the newest released standard?
As a general rule, use the latest standard if you can.
But, there are some reasons why you may in some situations choose to use an older one.
Your code makes use of features that changed behaviour in newer standards or were removed outright. If you don't have time to update your code, compiling for the older standard is reasonable.
Your tool-chain may not implement the new standard correctly. There could be known bugs that force you to stick to an older one.
You need to support multiple compilers on multiple platforms and not all combinations support the new standard yet.
You need to be binary compatible with code built by an older compiler for an older standard and you don't have the source to recompile it. In that case you may be forced to use the same old compiler and language standard to ensure ABI compatibility.
Internal company politics may mandate a specific version for arbitrary reasons.
Certification requirements may mandate use of a specific compiler and/or language version.
Familiarity with the new features may be low on your team, so using them may increase the risk of bugs.
Etc (I've seen all of the above happen in real life btw)..

Creating C++ API Library

I'm trying to understand the correct way, or right approach, to provide a reasonably large C++ API for a non-open source project. I do not want to provide a "header only" library as the code base is fairly large and meant to be closed source. The goals are as follows:
Provide a native C++ API that users may instantiate C++ classes, pass data around, all in C++, without a C-only wraper
Allow methods to take as parameters and return C++ objects, especially STL types (std::string, std::vector, etc)
No custom allocators
Most industry standard / canonical method of doing this possible, if such a standard exists
No re-creating COM or using MS COM
Assume all C++ compilers are at least C++11 "compliant"
I am targeting Windows as well as other platforms (Linux).
My understanding is creating a DLL or shared library is out of the question because of the DLL boundary issue. To deal with DLL boundary issue, the DLL and the calling code must be compiled with dynamically linked runtime (and the right version, multithreaded/debug/etc on Windows), and then all compiler settings would need to match with respect to debug symbols (iterator debugging settings, etc). One question I have this is whether, if, say on Windows, we ensure that the compiler settings match in terms of /MD using either default "Debug" and "Releas" settings in Visual Studio, can we really be "safe" in using the DLL in this way (that is passing STL objects back and forth and various things that would certainly be dangerous/fail if there was a mismatch)? Do shared object, *.so in Linux under gcc have the same problem?
Does using static libraries solve this problem? How much do compiler settings need to match between a static library and calling code for which it is linked? Is it nearly the same problem as the DLL (on Windows)?
I have tried to find examples of libraries online but cannot find much guidance on this. Many resources discuss Open Source solution, which seems to be copying header and implementation files into the code base (for non-header-only), which does not work for closed source.
What's the right way to do this? It seems like it should be a common issue; although I wonder if most commercial vendors just use C interfaces.
I am ok with static libraries if that solves the problem. I could also buy into the idea of having a set of X compilers with Y variations of settings (where X and Y are pre-determined list of options to support) and having a build system that generated X * Y shared binary libraries, if that was "safe".
Is the answer is really only to do either C interfaces or create Pure Abstract interfaces with factories? (if so, is there a canonical book or guide for doing this write, that is not implementing Microsoft COM?).
I am aware of Stefanus DuToit's Hourglass Pattern:
https://www.youtube.com/watch?v=PVYdHDm0q6Y
I worry that it is a lot of code duplication.
I'm not complaining about the state of things, I just want to understand the "right" way and hopefully this will serve as a good question for others in similar position.
I have reviewed these Stackoverflow references:
When to use dynamic vs. static libraries
How do I safely pass objects, especially STL objects, to and from a DLL?
Distributing Windows C++ library: how to decide whether to create static or dynamic library?
Static library API question (std::string vs. char*)
Easy way to guarantee binary compatibility for C++ library, C linkage?
Also have reviewed:
https://www.acodersjourney.com/cplusplus-static-vs-dynamic-libraries/
https://blogs.msmvps.com/gdicanio/2016/07/11/the-perils-of-c-interface-dlls/
Given your requirements, you'll need a static library (e.g. .lib under windows) that is linked into your program during the build phase.
The interface to that library will need to be in a header file that declares types and functions.
You might choose to distribute as a set of libraries and header files, if they can be cleanly broken into separate pieces - if you manage the dependencies between the pieces. That's optional.
You won't be able to define your own templated functions or classes, since (with most compilers) that requires distributing source for those functions or classes. Or, if you do, you won't be able to use them as part of the interface to the library (e.g. you might use templated functions/classes internally within the library, but not expose them in the library header file to users of the library).
The main down side is that you will need to build and distribute a version of the library for each compiler and host system (in combination that you support). The C++ standard specifically encourages various types of incompatibilities (e.g. different name mangling) between compilers so, generally speaking, code built with one compiler will not interoperate with code built with another C++ compiler. Practically, your library will not work with a compiler other than the one it is built with, unless those compilers are specifically implemented (e.g. by agreement by both vendors) to be compatible. If you support a compiler that supports a different ABI between versions (e.g. g++) then you'll need to distribute a version of your library built with each ABI version (e.g. the most recent version of the compiler that supports each ABI)
An upside - which follows from having a build of your library for every compiler and host you support - is that there will be no problem using the standard library, including templated types or functions in the standard library. Passing arguments will work. Standard library types can be member of your classes. This is simply because the library and the program using it will be built with the same compiler.
You will need to be rigorous in including standard headers correctly (e.g. not relying on one standard header including another, unless the standard says it actually does - some library vendors are less than rigorous about this, which can cause your code to break when built with different compilers and their standard libraries).
There will mostly be no need for "Debug" and "Release" versions (or versions with other optimisation settings) of your library. Generally speaking, there is no problem with having parts of a program being linked that are compiled with different optimisation settings. (It is possible to cause such things to break,if you - or a programmer using your library in their program - use exotic combinations of build options, so keep those to a minimum). Distributing a "Debug" version of your library will permit stepping through your library with a debugger, which seems counter to your wishes.
None of the above prevents you using custom allocators, but doesn't require it either.
You will not need to recreate COM unless you really want to. In fact, you should aim to ensure your code is as standard as possible - minimise use of compiler-specific features, don't make particular assumptions about sizes of types or layout of types, etc. Using vendor specific features like COM is a no-no, unless those features are supported uniformly by all target compilers and systems you support. Which COM is not.
I don't know if there is a "standard/canonical" way of doing this. Writing code that works for multiple compilers and host systems is a non-trivial task, because there are variations between how different compiler vendors interpret or support the standard. Keeping your code simple is best - the more exotic or recent the language or standard library feature you use, the more likely you are to encounter bugs in some compilers.
Also, take the time to set up a test suite for your library, and maintain it regularly, to be as complete as possible. Test your library with that suite on every combination of compiler/system you support.
Provide a native C++ API that users may instantiate C++ classes, pass data around, all in C++, without a C-only wraper
This excludes COM.
Allow methods to take as parameters and return C++ objects, especially STL types (std::string, std::vector, etc)
This excludes DLLs
Most industry standard / canonical method of doing this possible, if such a standard exists
Not something "standard", but common practises are there. For example, in DLL, pass only raw C stuff.
No re-creating COM or using MS COM
This requires DLL/COM servers
Assume all C++ compilers are at least C++11 "compliant"
Perhaps. Normally yes.
Generally: If source is to be available, use header only (if templates) or h +cpp.
If no source, the best is DLL. Static libraries - you have to build for many compilers and one has to carry on your lib everywhere and link to it.
On linux, gcc uses libstdc++ for the c++ standard library while clang can use libc++ or libstdc++. If your users are building with clang and libc++, they won't be able to link if you only build with gcc and libstdc++ (libc++ and libstdc++ are not binary compatible). So if you wan't to get target both you need two version of you library, one for libstdc++, and another for libc++.
Also, binaries on linux (executable, static library, dynamic library) are not binary compatible between distros. It might work on your distro and not work on someone else distro or even a different version of your distro. Be super careful to test that it work on whichever distro you want to target. Holy Build Box could help you to produce cross-distribution binaries. I heard good thing about it, just never tried it. Worst case you might need to build on all the linux distro you want to support.
https://phusion.github.io/holy-build-box/

Using C++17 'any' with Xcode 8.1

I am using C++ in Xcode version 8.1. I need to use the functionality of boost::any but am strongly opposed to pulling any part of Boost into our project (let's not debate it please).
I see that std::any is "merged into C++17" here.
I want to use this in my Xcode 8.1 project. I have tried using -std=c++1z as a custom flag on the project, but I can't seem to find a header for it.
How can I use std::any or std::experimental::any in my Xcode project?
Can I download the appropriate headers from an implementation and throw them into my project's sourcecode? Or, even better, is actually available to now in my version of Xcode/Clang/C++?
You can't say "I want the default Xcode compiler [which has no support for any]" and at the same time request it to support any. You also can't mix standard library headers for different compiler versions.
You can either
use a compiler version that provides std::any or
use any third party library that provides another any-like type.
Your installation setup does not have the c++17 standard. std::any simply is not available to you unless you get a compiler with at least experimental support for what you want.
Clang Cxx Status
You'd have a lot better luck just using boost::any probably.
If you're really set on not bringing a third party library into play, the reality is that creating your own any isn't that difficult. I don't recommend reinventing the wheel but in this case it's not that difficult.
Here's a SO question with an answer showing a way to do 'any'.
It is illegal to inject new types into std via a third party library. You can upgrade your compiler, get a distinct std library your compiler supports, or use a 3rd party library that provides any in another namespace, or write your own.
The first you said no to.
The second is hard, as xcode does not advertise what its compiler actually is. There are generally two common std libraries that work with clang-llvm derived compilers; libc++ and libstdc++. That kind of swap tends to be very expensive even if the other one has the feature you want.
The third is basically "use boost" or equivalent.
The last isn't hard; a few days work (mostly bugs after the fact), based on writing types of similar complexity, assuming "good enough" is good enough (ie, not getting caught up in ideal exception guarantees, or matching standard exactly, etc). An implementation will require hyperbolic effort to approach perfection, naturally.
Xcode 9.0 beta can now be downloaded (https://developer.apple.com/download/). It supports the c++17 flag option.
Edit: Xcode 9.2 is publically available with std::any support.

Is there a way to determine language features implemented by a C++ compiler?

Different C++ compilers implement the various language features at different points in time (see, e.g., clang C++ status and gcc c++ status; likewise for other compilers). When creating a C++ library it is often desirable to support the latest features to improve the user experience. When supporting new features rather than the common subset implemented everywhere it is helpful to know what features a compilers support without having to support a set of version numbers for each compiler.
Is there are reasonably standardized set of feature tests which can be used at compile time to determine if a specific language feature is supported by the compiler?
You probably can't do better than the Boost.Config library. It defines preprocessor macros for various C++11 and C++14 features which aren't universally supported on C++11/14-ish compilers like VC++. It's as close as you're going to get to standard.
IIRC, it works similarly to autoconf, by prebuilding (and, when necessary, executing) a bunch of simple test programs. I don't think you're going to get anything which operates entirely at compile-time, simply because there are things which are keywords in one implementation and syntax errors in another.
I haven't tried to use the recommendations but at the C++ committee meetings the Feature Test SG (SG10) meets and updates a list of recommendations. Here is the latest document listing the current feature test macros: there are macros for various language level features. The expectation is that the document P0096rx will be updated when new features are voted into the working draft.
This document is not a standards document: the standard mandates implementation of a language standard and it doesn't make sense to standardize macros indicating whether a specific features is implemented! An implementation is either fully conforming or not. However, the expectation is that compiler vendors do use these macros as guidance to help users.

std::map::emplace() missing - outdated libraries?

I'm trying to use the C++11 emplace() function of a map, but NetBeans says a map has no such function. Looking at the headers, it's "right" - there is no mention (on Fedora 16) of emplace(). Which is all well and good, you know... but I kinda wanna use emplace().
How do I go about enabling this functionality? I know for a fact that it's existed since March of last year, probably earlier. A thorough search shows that emplace() basically only exists on my system in the headers for lists and vectors. Since there hasn't been a major revision of C++ in almost a decade, I'm not having any luck finding documentation on what to do if the libraries are "wrong".
If your implementation doesn't support something, you have two choices:
don't use the feature
use another implementation which supports what you need.
The fact that there is a new standard doesn't widen the choices. In fact, it reduces it as you'll have additional difficulties in finding an implementation which supports everything that you want for each one your targets.
Note that for pure library things, the other implementation could be one you make: compatibility wrappers have an increased appearance in transition time. But you have to pay attention to name clashes effects (visibility of compatibility wrappers may add ambiguities to the code when the feature appears at its standard place).
GCC 4.7 does not support this as there were unresolved issues with the standard at the time. It is implemented in 4.8 and above. You will need -std=c++11