Are there any plans to add "expects" to std::optional? - c++

This topic is controversial, but I'm in the camp which believes that preconditions and class invariants should be guarded by asserts which terminate the program if the contract of the corresponding SW component is violated - as long as the runtime cost for the assertion checks is not a performance bottleneck.
I really like optional types and use them a lot, but for me the standard library implementations of std::optional are unusable as of now, since first the dereferencing of an optional does not perform checks whether it contains a value, and second none of the major c++ implementations support/implement assertions within standard library functions as of now.
From the use of std::optional I have seen over the years, I cannot recall a single instance where a std::optional was used in such a manner and quantity, such that precondition checks would be a performance bottleneck and prohibitive. For instance, I have never seen that somebody implemented a mask image as an array of std:optional's.
My question: Is there any proposal out already (e.g. for c++22), which adds contract features to the standard library, in particular std::optional?
Yes, I'm aware of the value method which is "guarded" by an exception.
First, I'm not a big fan of non-exceptional control flow using exceptions (have you ever tried to debug such code).
Second, I believe the strength and safety of a type should judged by its weakest link.
I can't comment yet, hence I comment on the answer by Nicol Bolas here:
Thanks for the answer, but I frankly I don't think it answers my question. Just to clarify. I'm not asking for a proposal which mandates that std::abort is called on contract violations (of an "expect" close). Instead, I'm asking whether there are any plans to add contract annotations to the standard library following the P0788 proposal. I agree that the standard should not mandate how specific implementations should deal with such contract violations.

This is kind of moot for the immediate future, since contracts was removed from C++20 for some reworking. However, I think the remaining text still applies:
Is there any proposal out already (e.g. for c++22), which adds design by contract support to the standard library, in particular std::optional?
Quite the opposite: the proposal P0788 was adopted and folded into the C++20 working paper, which states that preconditions/postconditions are not to be mandated to be implemented by the contract feature. The specific intent of P0788 was to prevent formalized requirements on implementations to use contracts for these things (or concepts for similar conditions):
Let’s avoid any specification that demands any particular technology by which implementations must comply with Library specifications.
Implementations are permitted to express such conditions as contracts, but are not required to. By adopting P0788, the committee is effectively considering such things to be a matter of implementation quality, not formal specification.
C++ is not a safe language, and contracts are not intended to make it so. Violating contracts is a programming error and yields UB, and that's how the standard sees things. And by design, there is no way for you to force your desire for safety upon those who don't want it.

Answer to my own question. Thanks for the discussion which pointed in the right direction.
Currently, the dereference operator of std::optional is annotated with an "Requires" clause.
In the spirit of P0788, I'd expect the Requires clause to be changed to Expects in the near future:
Let’s make it a goal, over time, to eliminate all Requires: elements from our Library
specifications, preferring our new elements instead.
Furthermore, standard library implementations are permitted to any technology to meet "Expects" specifications.
Let’s permit an implementation to use Contracts attributes [P0542R1] and/or any other
technologies to meet Expects: and Ensures: specifications.
So far, so good. Only the following statement makes it a little more tricky:
Let’s consider user code that relies on any specific technology on the part of an implementation to be ill-formed, with no diagnostic required
My interpretation of the above that users can't rely that standard implementations will guard Expects in any specific way or at all, but they may.
To the question:
Is there any proposal out already (e.g. for c++22), which adds contract features to the standard library, in particular std::optional?
Yes, contract annotations are already part of the standard.
It is up to the specific library implementation how to deal with "expect" clauses.

Related

Situation with `restrict` keyword/attribute in C++ standard

In short, restrict is supposed to tell the compiler that the pointers cannot point into the same memory location. Which is very useful for, say, function arguments and further compiler optimization. In scientific computing, restrict is very widely used.
Currently, restrict keyword is only a part of C99, but not a part of C++. We know that a lot of C++ compilers support __restrict__ as an extension. This question also talks in detail about what restrict and __restrict__ do.
Now, the discussion in the aforementioned question happened a long time ago and does not talk about C++17, C++20, nor plans for future standards. I found n3988 proposal that discusses restrict-like aliases in C++, complexities with richer syntaxis in C++, and potential remedies.
According to the IBM blog (2014), n3988 was encouraged for future work.
This question talks about the history of restrict and C++ without anything conclusive regarding the actual implementation and mentions the papers I already listed or the one mentioned in the comments (p1296).
I was not able to find anything beyond that on the plans of supporting restrict in the upcoming C++ (as far as I know, it's not a part of C++17). It seems like a very useful functionality, so I wonder
if I missed something in terms of proposals/discussion?
is there other information on the restrict usage in C++?
are there alternative ways to make the compiler optimizations (allowed by __restrict__) possible by using only "standard" functionality?
Nothing like C’s restrict is in even C++20. The paper already mentioned was well-received at a preliminary presentation in November 2018, perhaps because it avoids the critical difficulty with a qualifier—that no one, even in C, understands how it interacts with the rest of the type system. Part of this is because adding restrict doesn’t change the meaning of any one pointer, but affects its relationship with some set of other pointers (whose membership is not well-specified) based on what arithmetic is performed with them later. Another part is because C++ allows so many operations with types: what would std::vector<T *restrict> mean, and what would be the type of indexing a std::vector<T> &restrict?
Just what practical optimization opportunity will be offered by such a contract-based approach is not yet clear; there are still many unanswered questions about contracts and optimization in general.

Given Concepts, are SFINAE helpers still in the spec as non-deprecated?

It appears that Concepts can do everything you could have done using SFINAE based techniques, only much better. The list of advantages includes increased readability of overload resolution and enabling to make compiler diagnostics substantially less verbose.
One option, given that all of these Concepts' features are already part of the new draft, is that some or all of these SFINAE related helper templates be declared deprecated.
My main concern here is feature fragmentation.
My question is whether such a proposal for deprecation has in fact been submitted?
That seems like a rather pointless thing to do at this point. There is a lot of code out there using these templates, they won't be removed in the foreseeable future anyway.
Even removing trigraphs and the conversion from string literal to non-constant char* took quite a while, and at least the former was not even undisputed. (IBM wanted to keep them iirc.) Those templates have and had valid uses in current modern C++; they are here to stay†.
Note that deprecating a feature in the C++ standard is a fairly drastic step, placing it under review for future removal. It is meant to be a temporary state; either the feature gets removed at some point, or is restored to be non-deprecated:
With the release of a new C++ standard, we get an opportunity to revisit the features identified for deprecation, and consider if we are prepared to clear any out yet, either by removing completely from the standard, or by reversing the deprecation decision and restoring the feature to full service.
In an ideal world, the start of every release cycle would cleanse the list of deprecated features entirely, allowing the language and library to evolve cleanly without holding too much deadweight. In practice, C++ has some long-term deprecated facilities that are difficult to remove, and equally difficult to rehabilitate. Also, with the three year release cadence for the C++ standard, we will often be considering removal of features whose deprecated status has barely reached print.
From P0619R3, emphasize mine.
†At least for now. I'm not a member of the committee, so I can only speculate, but I would not rule out the possibility of deprecation at some point in the future, after concepts have settled in and if it becomes evident that the old helper templates do more harm than good.

Why is the restrict keyword not part of C++?

The title says it all. I am curious why is the restrict keyword not part of C++ ? I don't know much about C++, and I'm still not able to find anything online that would give a reason blocking this. Does anyone know what terrible things would happen, if a C++ standard would use this keyword similarly to the way C does? Is it just not needed at all?
More explanation: It is not about using it, perhaps I will not have any benefit from this keyword in my whole life. This question is only about curiosity, since restrict is part of C since C99, that is 15 years.
Read this as well:
I'm interested in technical reasons, not opinions like "They just didn't like, it is not cool enough"
There are several issues in defining "restrict" in C++, some of them are listed in WG paper N3635: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3635.pdf "Towards restrict-like semantics for C++"
Some possible issues with restrict in C++ are:
Restrict Class members and indirection with “this pointer”
Passing of restrict qualifiers into functions, functors, lambdas, and templates
Escaping of restrict pointer values inside functions
Overlapping array members, strides
Document also list several C++ compilers with limited "restrict" support for C++.
There is also interesting history note in N3635 about non-inclusion of restrict to C++:
At the time of reviewing C99 feature inclusion in C++ during the Mont Tremblant meeting, restrict was considered but was waiting a paper proposal although none came forward....
Restrict is a C99 feature and was never designed to work in class abstractions and it may have to do with that pointers are not common in C++. ... it was designed for fine-grain aliasing for C, but not well-designed for type-based aliasing in C++
Not to detract from osgx's answer, but - there is a somewhat more up-to-date paper, N3998 by Finkel, Tong, Carrouth, Nelson Vandevoode and Wong, from May 2014:
Towards restrict-like aliasing semantics for C++
And an ever newer one from 2018:
[[assert: std::disjoint(A,nA, B,nB)]]: Contract assertions as an alternate
spelling of ‘restrict’
(Thanks #MCCCS for pointing the last one out.)

Why were concepts (generic programming) conceived when we already had classes and interfaces?

Also on programmers.stackexchange.com:
I understand that STL concepts had to exist, and that it would be silly to call them "classes" or "interfaces" when in fact they're only documented (human) concepts and couldn't be translated into C++ code at the time, but when given the opportunity to extend the language to accomodate concepts, why didn't they simply modify the capabilities of classes and/or introduced interfaces?
Isn't a concept very similar to an interface (100% abstract class with no data)? By looking at it, it seems to me interfaces only lack support for axioms, but maybe axioms could be introduced into C++'s interfaces (considering an hypothetical adoption of interfaces in C++ to take over concepts), couldn't them? I think even auto concepts could easily be added to such a C++ interface (auto interface LessThanComparable, anyone?).
Isn't a concept_map very similar to the Adapter pattern? If all the methods are inline, the adapter essentially doesn't exist beyond compile time; the compiler simply replaces calls to the interface with the inlined versions, calling the target object directly during runtime.
I've heard of something called Static Object-Oriented Programming, which essentially means effectively reusing the concepts of object-orientation in generic programming, thus permitting usage of most of OOP's power without incurring execution overhead. Why wasn't this idea further considered?
I hope this is clear enough. I can rewrite this if you think I was not; just let me know.
There is a big difference between OOP and Generic Programming, Predestination.
In OOP, when you design the class, you had the interfaces you think will be useful. And it's done.
In Generic Programming, on the other hand, as long as the class conforms to a given set of requirements (mainly methods, but also inner constants or types), then it fits the bill and may be used. The Concept proposal is about formalizing this, so that detection may occur directly when checking the method signature, rather than when instantiating the method body. It also makes checking template methods more easily, since some methods can be rejected without any instantiation if the concepts do not match.
The advantage of Concepts is that you do not suffer from Predestination, you can pick a class from Library1, pick a method from Library2, and if it fits, you're gold (if it does not, you may be able to use a concept map). In OO, you are required to write a full-fledged Adapter, every time.
You are right that both seem similar. The difference is mainly about the time of binding (and the fact that Concept still have static dispatch instead of dynamic dispatch like with interfaces). Concepts are more open, thus easier to use.
Classes are a form of named conformance. You indicate that class Foo conforms with interface I by inheriting from I.
Concepts are a form of structural and/or runtime conformance. A class Foo does not need to state up front which concepts it conforms to.
The result is that named conformance reduces the ability to reuse classes in places that were not expected up front, even though they would be usable.
The concepts are in fact not part of C++, they are just concepts! In C++ there is no way to "define a concept". All you have is, templates and classes (STL being all template classes, as the name says: S tandard T emplate L ibrary).
If you mean C++0x and not C++ (in which case I suggest you change the tag), please read here:
http://en.wikipedia.org/wiki/Concepts_(C++)
Some parts I am going to copy-paste for you:
In the pending C++0x revision of the C++ programming language, concepts and the related notion of axioms were a proposed extension to C++'s template system, designed to improve compiler diagnostics and to allow programmers to codify in the program some formal properties of templates that they write. Incorporating these limited formal specifications into the program (in addition to improving code clarity) can guide some compiler optimizations, and can potentially help improve program reliability through the use of formal verification tools to check that the implementation and specification actually match.
In July 2009, the C++0x committee decided to remove concepts from the draft standard, as they are considered "not ready" for C++0x.
The primary motivation of the introduction of concepts is to improve the quality of compiler error messages.
So as you can see, concepts are not there to replace interfaces etc, they are just there to help the compiler optimize better and produce better errors.
While I agree with all the posted answers, they seem to have missed one point which is performance. Unlike interfaces, concepts are checked in compile-time and therefore don't require virtual function calls.

How do you keep track of exception safety guarantees offered by each function

When writing exception safe code, it is necessary to consider the exception safety guarantee (none, basic, strong or no-throw) of all the functions called. Since the compiler offers no help, I was thinking that a function naming convention might be helpful here. Is there any kind of established notational standard indicating the level of exception safety guarantee offered by functions? I was thinking along the lines of something hungarian-like:
void setFooB(Foo const& s); // B, offers basic guarantee
int computeSomethingS(); // S, offers strong guarantee
int getDataNT() throws(); // NT, offers no-throw
void allBetsAreOffN(); // N, offers no guarantee
Edit: I agree with comments that this kind of naming convention is ugly, so allow me to elaborate on my reasons for suggesting in.
Say I refactor some code, and in that process, change the level of exception safety offered by a function. If the guarantee has changed from, say, strong to basic (justified perhaps by improvement in speed), then every function that calls the refactored function must be reconsidered for their exception safety. If the change in guarantee triggered a change in the function name as well, it would allow the compiler to help me out a little bit in at least flagging all uses of the changed function. This was my rationale for suggesting the naming convention above, problematic as it is. This is very similar to const, where a change in the const-ness of a function has cascading effects on other calling functions, but in that situation the compiler gives very effective assistance.
So I guess my question is, what kind of work habits have people developed in order to ensure that code actually fullfills their intended exception guarantees, especially during code maintenance and refactoring.
I usually find myself documenting that in comments (doxygen), excepts the no throw guarantee, that I often tag with the throw() exception specification if and only when sure that the function is guaranteed not to throw, and exception safety is important.
That is, I usually worry more about exceptions in parts of the code where an unhandled exception would cause problems, and deal with that locally (ensure that your code is exception safe by other means, as RAII, performing the work outside and then merging the results with a no throw operation --i.e. no throw swap, which is about the only function that I actively mark as throw().
Other people might have other experiences, but I find that to be sufficient for my daily work.
I don't think you need to do anything special.
The only ones I really document are no-throw and that is because the syntax of the language allows it.
There should be no code in your project that provides no guarantee. So that only leaves strong/basic to document. For these I don't think you need to explicitly call it out as it not really about the methods themselves but the class as a whole (for these two guarantees). The guarantees they provide are really dependent on usage.
I would like to think I provide the strong guarantee on everything (but I don't) sometimes it is too expensive sometimes its just not worth the effort (if things are going to throw they will be destroyed anyway).
I understand your willingness to do well, but I am unsure about such a naming convention.
I am, in general, wary of naming conventions that are not enforced by the language: they are prone to become the greatest liars.
If you truly need such things, my suggestion is to get your hands on a compiler (Clang for example) and add a new set of attributes. Do note that you'll need to edit your Standard Library provided headers, and all 3rd party headers you rely on, to annotate them so that you can get those guarantees from the ground up.
Then you can have the compiler check the annotations (won't be trivial either...), and then the annotations become useful, because they cannot lie.
I am thinking about adding
#par Exception Safety
Strong guarantee
to my javadocs where appropriate.