92

I have a project that currently uses C++11/14, but it requires something like std::filesystem, which is only available in C++17, and hence I don't have a chance to currently use it. I see, however, that it's available in my current compiler as std::experimental::filesystem. Is it a good idea to use experimental features, assuming that I could in the future add something like:

#ifdef CXX17 //if this is C++17
std::filesystem::something ...;
#else
std::experimental::filesystem::something ...;
#endif

My concerns are:

1. Is it guaranteed that all compliant compilers have the same experimental features?

2. Are experimental features prone to big changes that make them unreliable?

Maybe there's more things to wonder about. Why should I or should I not use them? I'm puzzled with a new project and don't know what to decide.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • 26
    doesn't the word **experimental** answer your questions? – 101010 Apr 10 '17 at 08:45
  • 1
    @101010 Not really. It's a little ambiguous. All I could find is that it "might" be added in a future standard or might be removed. But I know it's added. So the question is about the difference. – The Quantum Physicist Apr 10 '17 at 08:46
  • 6
    Mainly a matter of taste, but I would avoid to clutter the code with `#idef CXX17`. IMHO, the portable way is to put all filesystem related code in one single compilation unit (may be a class), use it throughout the remaining parts of the code, code it with current C++11/14 standard. Document how an why you write it like that, and eventually port it to C++17 later during a maintenance phase, if it makes sense. (commenting on the original question) – Serge Ballesta Apr 10 '17 at 08:47
  • 4
    It was only "experimental" as a candidate to enter the standard. It is not a reflection of the quality of the code. – Galik Apr 10 '17 at 08:47
  • @Galik That's exactly why I think it's ambiguous (referring to 101010's statement in the comments). – The Quantum Physicist Apr 10 '17 at 08:48
  • @SergeBallesta Honestly this is how I'm doing it now :) , but I'm trying to see whether I have easier options. – The Quantum Physicist Apr 10 '17 at 08:51
  • 5
    There were quite a few changes between the "experimental" and final C++17 version, see [document P0492R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0492r1.html) – Bo Persson Apr 10 '17 at 08:54
  • 7
    In the case of `filesystem` you incur far less risk in using it than other things, as you already know that it gets standardized in C++17, and the exact C++17 specification of it is publicly available. So all you have to do is make sure that you use only the `experimental::filesystem` features that are in C++17 specification. And of course you have to know that all of your targeted platforms support one of `experimental::filesystem` or the C++17 `std::filesystem`. – Howard Hinnant Apr 10 '17 at 12:57
  • you'll have to global search-and-replace `std::experimental::filesystem` --> `std::filesystem` when it does get standardized ! – M.M Apr 10 '17 at 23:09
  • 3
    One thing to consider is that, while the answers here are good, the single most important question when making these decisions is "what is your development environment like?" If your environment has a habit of having anemic maintenance budgets that barely keep food on the table and bits in the hard drive, you probably don't want to saddle your future developers with experimental stuff. On the other hand, if you're on a long term agile project that's constantly putting new energy into the system, the benefits may outweigh the costs. – Cort Ammon Apr 10 '17 at 23:44
  • As another example, if you're doing mission critical stuff like nuclear powerplant management, or even just ABS brake management systems, you will likely have a body which is responsible for blessing any library feature you use. That governing body may have something to say about a volatile namespace! – Cort Ammon Apr 10 '17 at 23:46
  • 1
    **Moderator note**: I've removed the long-winded and often very unconstructive discussion about the merits of this post. Please take such discussions to [Meta] or [chat] next time. This is not the place to tell people how to use their votes or to ascribe motivations to others. – Martijn Pieters Apr 12 '17 at 10:31
  • 1
    +1 to @HowardHinnant's comment above. Re-read that. Another alternative is to look for the source of the `experimental` library -- in the case of `filesystem`, `optional`, etc., that is Boost. If you are permitted to use Boost, you could get a reasonably stable, portable interface there, which should about as straightforward to port to C++17 as `std::experimental`. – metal Apr 14 '17 at 13:17
  • @metal I agree. Actually I'm using boost currently with an abstract interface that I made, but was hoping I could rely on the standard only. – The Quantum Physicist Apr 14 '17 at 13:24
  • @TheQuantumPhysicist Do note that (1) there are bugs in Boost.Filesystem still being fixed (e.g., [this one](https://github.com/boostorg/filesystem/pull/37) that I reported and was fixed recently) and (2) the C++17 gang will have thought *even harder* about the corner-cases such as non-POSIX filesystems like Windows, which is the most likely place for changes (see MSalters's answer below). – metal Apr 14 '17 at 14:43
  • 1
    On the positive side, the author of Boost.Filesystem is also the same person that has shepherded `std::filesystem` though the standardization process. :-) – Howard Hinnant Apr 14 '17 at 14:47

4 Answers4

82
  1. Is it guaranteed that all compliant compilers have the same experimental features?

No, experimental features are optional.

  1. Are experimental features prone to big changes that make them unreliable?

Yes, the C++ committee might even decide to abandon a feature or in the process of standardization a defect might come up that would force a feature to change.

Generally, it's not a good idea to depend on experimental features. Experimental features are exactly what the word says (i.e., to experiment with).

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
101010
  • 41,839
  • 11
  • 94
  • 168
  • 2
    Referring to the second point, please note that I'm talking about features that are already accepted, but *might* be different. – The Quantum Physicist Apr 10 '17 at 08:50
  • 14
    @TheQuantumPhysicist: "already accepted" is a tricky concept. Anything can be removed at any time by later acceptance of a change to remove it, and this has happened to every standard. You'd probably want to wait until at least the Draft International Standard before the feature set is reasonably reliable. – Kerrek SB Apr 10 '17 at 09:03
  • 1
    @KerrekSB: Don't you mean the _Final_ Draft International Standard aka FDIS. ? Drafting is a pretty permanent process. – MSalters Apr 10 '17 at 09:46
  • 1
    @MSalters: No, the DIS is probably good enough if you're in a hurry. And we may not have an FDIS this time anyway. – Kerrek SB Apr 10 '17 at 10:03
  • 1
    @KerrekSB: I don't think you can skip the FDIS step. FDIS is the document which ISO sends for approval to the National Bodies. – MSalters Apr 10 '17 at 10:26
  • 1
    @MSalters: Ah OK - you know more about this than me :-) – Kerrek SB Apr 10 '17 at 10:28
  • 4
    @KerrekSB: I pretty much was the National Body for the Netherlands around C++03 ;). We had a national secretary for SC22 which knew about ISO procedures and how to reply to an FDIS, but not what. Other than our WG14 delegate Randy Marques) none of our SC22 delegates knew anything about C++. And Randy was just making fun of the fact that C++ would need more pages to define all its UB than C needed for the Defined Behavior - wouldn't want him to reply to that FDIS ;) – MSalters Apr 10 '17 at 13:56
  • 1
    @MSalters Actually, you can skip FDIS if there are no "no" votes on the DIS (or something like that); C++14 skipped FDIS and C++17 is planning to do that too. – T.C. Apr 10 '17 at 15:48
  • @T.C.: I guess that's why we had a secretary, to get those things right. ISO might be a bit bureaucratic, but it works. – MSalters Apr 11 '17 at 07:41
53

Someone from the audience asked a question during the "C++ Standard Library Panel" talk at CppCon 2016 (YouTube) about the potential for the name experimental to scare users away from using anything within the namespace:

Do you guys consider [the contents of the std::experimental namespace] production ready and is that an argument that can be made, [that] it's effectively production ready for the next 3 years, and maybe you have to change your code 3 years later, maybe?

Michael Wong (chair of SG5 and SG14 and editor of the Concurrency TS) fielded the question first:

I think there's strong consensus within the committee that it is practically production ready. As I said before, in most cases 99% of it gets air-dropped in. We want to make sure that it's not an impediment for you to use it. You can understand why we want to put big features, large groups of features, in such a context, so that it doesn't disturb the rest of the whole library system, but it also makes it easier for you to use it. Now you can turn on GCC with a specific flag for Concepts, you know, that actually makes it easier for you to segment it out.

Alisdair Meredith (former chair of the LWG) then followed up:

I'm going to take the contrary position here. One of the things Herb [Sutter] said as convener of WG21, the standard group, when we set off down the path of TSes is, he didn't think that TSes will have succeeded until we have failed to bring something forward, because it means we're not being experimental enough, we're not being ambitious enough in what we're using the TSes for. We really do want that experimental to be a hint that, yes, these things are subject to change, we're not binding to that, and we can get things wrong. This is to lower our barrier for the things we consider to be as ambitious and reach as we can [...] Now the standard seems to be on a three-year release cycle, we should be much more ambitious in putting really experimental features into the TS, and perhaps advancing things more rapidly into the main standard itself. But again, this will be a fun topic for us to discuss at the next few [C++ standard committee] meetings.

Stephan T. Lavavej (maintainer of Microsoft's STL implementation) was last to respond:

It's important to draw a distinction between the experimentalness of interface and the experimentalness of the implementation, because when you say "production ready", what does that mean? Usually, "production ready", you would think of that talking about the implementation. It's quite possible for an implementation [of something in std::experimental] to be absolutely [...] bulletproof. [...] Something like [...] the <random> header in TR1, [it was] really, really nice in TR1, and you could have had an absolutely bullet-proof implementation of that, but it turned out that the interface churned substantially [before the release of] C++11 and [...] if we knew back then what we do now, putting in an experimental would have been a better signal to people that, "Hey, maybe you don't want to use std::experimental::variate_generator because, ha-ha, it's going to disappear in C++11".

So it seems that there is some desire among the standard library developers and committee members that, in the future at least, the contents of the std::experimental namespace should be truly "experimental" in nature, and it should not be taken for granted that something in std::experimental will make it into the C++ standard.

And no, as far as I understand, it is up to standard library vendors as to whether they provide implementations for the various features within std::experimental.

Cubbi
  • 46,567
  • 13
  • 103
  • 169
Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38
  • 53
    10 years after I first read the name, the fact that Microsoft's STL maintainer is named STL still makes me chuckle. – Jörg W Mittag Apr 10 '17 at 12:10
  • 24
    @JörgWMittag you should meet their compiler maintainer, Michael Sam Victor Collins – M.M Apr 10 '17 at 23:16
28

"Experimental" is a slightly exaggerated term. The filesystem library originated in Boost and went through a few iterations there, before being submitted to ISO.

However, ISO standards are intentionally very conservative. Calling it experimental means ISO explicitly doesn't promise that the naming will be stable; it's abundantly clear that you will need to re-address your code some time in the future. But knowing ISO, it's likely that there will be guidance how.

As for compatibility between compilers, expect it to be reasonable. But there will be corner cases (think Windows drive-relative paths for instance), and that's exactly why a future standard might break your existing code. Ideally, it would break you code if and only if you depended on that corner case, but that's not a guarantee.

MSalters
  • 173,980
  • 10
  • 155
  • 350
8

Maybe there's more things to wonder about.

A few points to consider:

  • How multiplatform is your project? If there is only one compiler involved, then you can inspect its implementation and track record to decide. Or ask them!

  • How large is your codebase? How large would be the impact of changes?

  • How fundamental to your project are the features provided by the API/library/feature?

  • What are the alternatives?

    • Use experimental feature, then adapt code to modifications when/if it becomes standardized. Might be as easy as deleting experimental::, or as hard as forcing workarounds.
    • Add an abstraction layer (Serge Ballesta comment). If the experimental feature changes your re-writes are isolated. For a standard feature, it might be overkill (std::filesystem is already an abstraction layer...).
    • Use another API/library. Same questions: maturity? robustness? stability? portability? ease of use? features?
  • In the case of std::filesystem (or the networking TS), there is boost::filesystem (resp. boost::asio) as an alternative or fallback, in case the experimental one fails or desappears.
Pablo H
  • 609
  • 4
  • 22