Standardization

Trip Report: C++ Standards Meeting in Jacksonville, February 2016--Botond Ballo

ANother trip report:

Trip Report: C++ Standards Meeting in Jacksonville, February 2016

by Botond Ballo

From the article:

Last week I attended a meeting of the ISO C++ Standards Committee in Jacksonville, Florida. This was the first committee meeting in 2016; you can find my reports on the 2015 meetings here (May 2015, Lenexa) and here (October 2015, Kona). These reports, particularly the Kona one, provide useful context for this post...

P0141R0: Modules, Componentization, and Transition by Gabriel Dos Reis and Pavel Curtis

A new WG21 paper is available. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: P0141R0

Date: 2015-10-05

Modules, Componentization, and Transition

by Gabriel Dos Reis and Pavel Curtis

Excerpt:

We provide an analysis of constraints for a good, acceptable, and scalable module system for modern C++. This analysis is based on decades of practical experience with precompiled headers, and 40+ years of the include-file model, which has shown its limits. The paper also discusses several migration strategies. The end goal is to stimulate a technical discussion about the difficult choices we face in bringing C++’s compilation model into the era of semantics-aware developer tools, and of smart distributed and cloud build systems.

P0221R1: Proposed wording for default comparisons, revision 3 -- Jens Maurer

A new WG21 paper is available. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: P0221R1

Date: 2016-03-17

P0221R1: Proposed wording for default comparisons, revision 3

by Jens Maurer

Excerpt:

Introduction

This paper presents design rationale and proposed wording to implement default comparisons for class types. It is a revision of N4532 with additional updates from the Evolution Working Group session at the Kona meeting of WG21 and in-depth discussions with interested parties.

This paper assumes that the reader is familar with N4475 "Default comparisons (R2)" by Bjarne Stroustrup. In particular, default comparisons are assumed to be implicit (i.e. require no extra syntax to be available).

P0221R0 amended by a clarification for template specializations was approved by EWG during the Jacksonville (2016-03) meeting of WG21. Blue text in the proposed wording indicates changes compared to P0221R0.

Changes since P0221R0

  • fix wording glitches
  • clarified the zero-subobject (= empty class) cases
  • clarified that the context for a subobject comparison is the top-level class definition
  • clarified that both slicing copy and slicing move are prohibited
  • two-phase name lookup applies when comparing members whose type was instantiated from a dependent type

P0206R1: A joining thread -- Ville Voutilainen

A new WG21 paper is available. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: P0206R1

Date: 2016-03-09

A joining thread

by Ville Voutilainen

Excerpt:

Changes from previous version

  • This paper revises P0206R0.
  • Removed the motivation elaboration, it can be found in the previous revision.
  • Removed the discarded solutions.
  • Added explanation for the std::thread-accessing functions and discarded alternatives for it.
  • Renamed safe_thread to joining_thread.
  • Used thread::id and thread::native_handle_type in joining_thread.
  • Updated proposed wording.

Abstract

C++ continues not to provide a thread type that would join() automatically on scope exit. This causes exception-safety problems, because failing to join() in all code paths causes the destructor of a std::thread to terminate(). This paper provides a solution that adds a new thread type that joins in its destructor, and is based on large-group and LEWG feedback given in Jacksonville. The proposal has been implemented and tested. 

Jacksonville approved papers and issues

The following is a list of the papers approved at the Jacksonville meeting that ended on Saturday. Some of the papers appeared in the pre-meeting mailing or an earlier mailing; most were updated during the meeting and for convenience this post includes and links to copies of the approved papers. All updated approved papers will appear also in the official post-meeting mailing, as will the official minuted form of the following notes.

More readable summaries will be posted in trip reports. This post is primarily making the papers available for linking and reference.

 

Accept as Defect Reports the issues in P0167R2 (Core Language "ready" Issues) and apply their proposed resolutions to the C++ working paper.

Accept as Defect Reports the issues in P0263R1 (Core Language "tentatively ready" Issues) and apply their proposed resolutions to the C++ working paper.

Apply to the C++ working paper the proposed wording in P0188R1 ("Wording for [[fallthrough]] attribute").

Apply to the C++ working paper the proposed wording in P0189R1 ("Wording for [[nodiscard]] attribute").

Apply to the C++ working paper the proposed wording in P0212R1 ("Wording for [[maybe_unused]] attribute").

Apply to the C++ working paper the proposed wording in P0017R1 ("Extension to aggregate initialization").

Apply to the C++ working paper the proposed wording in P0170R1 ("Wording for Constexpr Lambda").

Apply to the C++ working paper the proposed wording in P0036R0 ("Unary Folds and Empty Parameter Packs (revision 1)").

Apply to the C++ working paper the proposed wording in P0184R0 ("Generalizing the Range-Based For Loop").

Apply to the C++ working paper the proposed wording in P0018R3 ("Lambda Capture of *this by Value as [=,*this]").

Apply to the C++ working paper the proposed wording in P0138R2 ("Construction Rules for enum class Values").

Apply to the C++ working paper the proposed wording in P0245R1 ("Hexadecimal floating literals for C++").

Request a new work item for a Technical Specification on C++ Extensions for Modules and create a working paper with P0143R2 ("Wording for Modules") as its initial content.

 

Apply the resolutions of the following issues in "Ready" status from P0165R1 to the C++ Working Paper:

2276 Missing requirement on std::promise::set_exception
2523 std::promise synopsis shows two set_value_at_thread_exit()'s for no apparent reason
2537 Constructors for priority_queue taking allocators should call make_heap

Note that the following issues, marked Ready in the paper, are not being advanced:

2253 [arrays.ts] dynarray should state which container requirements aren't met
2255 [arrays.ts] dynarray constructor ambiguity

 

Apply the resolutions of the following issues in "Tentatively Ready" status from P0165R1 to the C++ Working Paper:

2192 Validity and return type of std::abs(0u) is unclear
2450 (greater less greater_equal less_equal)<void> do not yield a total order for pointers
2520 N4089 broke initializing unique_ptr<T[]> from a nullptr
2545 Simplify wording for bind without explicitly specified return type
2557 Logical operator traits are broken in the zero-argument case
2559 Error in LWG 2234's resolution
2560 is_constructible underspecified when applied to a function type
2565 std::function's move constructor should guarantee nothrow for reference_wrappers and function pointers
2566 Requirements on the first template parameter of container adaptors
2571 §[map.modifiers]/2 imposes nonsensical requirement on insert(InputIterator, InputIterator)
2572 The remarks for shared_ptr::operator* should apply to cv-qualified void as well
2576 istream_iterator and ostream_iterator should use std::addressof
2577 {shared,unique}_lock should use std::addressof
2579 Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assign
2581 Specialization of <type_traits> variable templates should be prohibited
2582 §[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits
2583 There is no way to supply an allocator for basic_string(str, pos)
2585 forward_list::resize(size_type, const value_type&) effects incorrect
2586 Wrong value category used in scoped_allocator_adaptor::construct()
2590 Aggregate initialization for std::array

 

Apply the resolutions of the following issues in "Tentatively Ready" status from P0165R1 to the Library Fundamentals Working Paper:

2522 [fund.ts.v2] Contradiction in set_default_resource specification
2539 [fund.ts.v2] invocation_trait definition definition doesn't work for surrogate call functions
2558 [fund.ts.v2] Logical operator traits are broken in the zero-argument case
2574 [fund.ts.v2] std::experimental::function::operator=(F&&) should be constrained
2575 [fund.ts.v2] experimental::function::assign should be removed

 

Apply to the C++ Working Paper the Proposed Wording from P0024R2, The Parallelism TS Should be Standardized.

Apply to the C++ Working Paper the Proposed Wording from P0226R1, Mathematical Special Functions for C++17, v5.

Apply to the C++ Working Paper the Proposed Wording from P0220R1, Adopt Library Fundamentals V1 TS Components for C++17 (R1).

Apply to the C++ Working Paper the Proposed Wording from P0218R1, Adopt the File System TS for C++17.

Apply to the C++ Working Paper the Proposed Wording from P0033R1, Re-enabling shared_from_this (revision 1).

Apply to the C++ Working Paper the Proposed Wording from P0005R4, Adopt not_fn from Library Fundamentals 2 for C++17.

Apply to the C++ Working Paper the Proposed Wording from P0152R1, constexpr atomic::is_always_lock_free.

Apply to the C++ Working Paper the Proposed Wording from P0185R1, Adding [nothrow-]swappable traits, revision 3.

Apply to the C++ Working Paper the Proposed Wording from P0253R1, Fixing a design mistake in the searchers interface.

Apply to the C++ Working Paper the Proposed Wording from P0025R0, An algorithm to "clamp" a value between a pair of boundary values.

Apply to the C++ Working Paper the Proposed Wording from P0154R1, constexpr std::hardware_{constructive,destructive}_interference_size.

Apply to the C++ Working Paper the Proposed Wording from option #2 in P0030R1, Proposal to Introduce a 3-Argument Overload to std::hypot.

Apply to the C++ Working Paper the Proposed Wording from P0031R0, A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access and apply the resolution of LWG Issue 2296 - std::addressof should be constexpr. This issue is published in P0304R0.

Apply to the C++ Working Paper the Proposed Wording from P0272R1, Give 'std::string' a non-const '.data()' member function.

Apply to the C++ Working Paper the Proposed Wording from P0077R2, is_callable, the missing INVOKE related trait.

Trip Report C++ Meeting at Jacksonville -- J. Daniel Garcia

Here is Daniel's trip report from the recent C++ meeting at Jacksonville

Trip Report C++ Meeting at Jacksonville

by J. Daniel Garcia

From the article:

First of all the bad news. Unfortunately I have to say that the outcome of the standards meeting has been disappointing. Let me explain myself. We had a really very intense week here in Jacsonville. We made progress in many things, but  we will not have the killer features I really wanted for C++17.

In detail he sums the features that were not voted into C++17 and those that were accepted.

 

C++17 and its Technical Specifications

The 2nd part of my series on proposals for C++17 deals with Technical Specifications:

C++17 and its Technical Specifications

by Jens Weller

From the article:

Part 2 of my series about the current proposals for C++17. This part is covering the Technical Specifications (TS), which are currently released. Some of them will make it into C++17. Those not making it into C++17...

a bit of background for concepts and C++17 -- Bjarne Stroustrup

In about 1987, I tried to design templates with proper interfaces. I failed. I wanted three properties for templates: full generality/expressiveness, zero overhead compared to hand coding, and good interfaces. I got Turing completeness, better than hand-coding performance, and lousy interfaces. The lack of well-specified interfaces led to the spectacularly bad error messages we saw over the years. The other two properties made templates a run-away success.

The solution to the interface specification problem was named “concepts” by Alex Stepanov. A concept is a set of requirements on a set of template arguments. “Concepts” is currently an ISO TS and it is proposed to be put into the standard proper for C++17. A concept is a compile-time predicate. For example, if a template takes a type argument, we can specify that an argument, T, can be an iterator, Iterator<T>, a random access iterator, Random_access_iterator<T>, or maybe a number, Number<T>. Similarly, we can specify that a set of template arguments must meet a predicate, for example Mergeable<In1, In2, Out>. This is very expressive and nicely cheap to compile (cheaper than using template metaprogramming workarounds). Students can use it after a lecture or two. You can, of course, define your own concepts and we can have libraries of concepts. Concepts enable overloading and eliminate the need for a lot of ad-hoc metaprogramming.

It was not easy to get to this point. In the early 2000s there were several ideas, including the one that became the current approach. However, we struggled with an approach based on specifying requirements as sets of functions. Dealing with implicit conversions was hard, interactions between existing unconstrained templates and templates with concepts were hard to manage, and writing a compiler that generated acceptable code took heroic efforts by Doug Gregor. Compilation speed was nowhere near acceptable, though. In the end, the committee pulled the plug on the C++0x concepts.

But we still wanted and needed concepts! Together with Gabriel Dos Reis and Andrew Sutton, I started to re-design concepts from scratch. In 2011, Alex Stepanov called a meeting in Palo Alto, where a largish group, including Sean Parent and Andrew Lumsdaine, attacked the problem from the user’s perspective: What would a properly constrained STL look like? Then, we went home to invent language mechanisms to approximate that ideal. That re-booted of the standards effort and led to the current TS and compiler. Andrew Sutton’s implementation has been used for over three years now and is part of GCC 6.0.

The current concept design focuses on the specification of interfaces. This has led some people to (wrongly) conjecture that we did not care about checking of template definitions and that concepts (as opposed to C++0x concepts) could not be used for that. In reality, the 2006 POPL paper shows how to do definition checking, Gabriel Dos Reis’ experimental language Liz implements those ideas, and recently Andrew Sutton quickly demonstrated that our predicate model easily handles definition checking even when implicit conversions and move operations are used. What we do worry about is how to gradually convert large C+98-style code bases to use definition checking and how to allow data collection, tracing, telemetry, etc. without interface changes.

We should have concepts in C++17, not just in a TS. “Concepts” as specified in the TS is an immensely useful feature for designers of generic code and together with constexpr functions lead to greatly simplified and more maintainable code. Sadly, the concepts-based Ranges library is by some deemed not ready for C++17, so it is likely to stay a TS for a while, – even though concepts were designed to exactly match the requirements of the STL algorithms.

A bit of background for the default comparison proposal -- Bjarne Stroustrup

In 2014, Oleg Smolsky proposed to add default member functions defining comparisons. That re-ignited a decades-old debate. I once asked Dennis Richie why C didn’t provide a built-in == (equality) the way it provides a built-in = (copy). The answer was that until 1978 C didn’t have = for structs either, and copying could be efficiently implemented by something like memcpy(), but comparison couldn’t because the layout of structs included “holes” caused by alignment that had to be ignored. The days where compilers could handle individual members one by one and still generate optimal code for them were still far in the future, so I postponed dealing with comparisons. If you wanted one, you could write it yourself. That’s true, but many people, including Alex Stepanov, have objected to the inconvenience.

The killer argument for default comparisons is not actually convenience, but the fact that people get their equality operators wrong. They forget to compare all elements (especially when updating a struct with a new member). Also, given inheritance, a X::operator==(const X&) is easy to misuse (whether virtual or not). We get slicing (b==d will work even if b and d are of different classes in a hierarchy, and usually give a wrong answer). If people define operator==() as a member; then the left- and right-hand operand obey different conversion rules. Also, defining the semantics for == and != is relatively simple, but there are subtleties about other operators, such as <=; does its meaning involve < and == or < and !? Contrary to “common knowledge” there seems to be little difference in performance.

Lots of people joined the discussions and the discussions went all over the place. How do we handle pointers? (we don’t), how do we handle mutable members?, should we use static reflection?, etc., etc., At times, I thought that we would get nothing. That wouldn’t be a tragedy because default comparisons are not on my (mostly mythical) top-20 list of desirable improvements to C++. However:

  • I started trying to design == in analogy to = as if Dennis and I had been doing it in 1980 or so.
  • Jens Maurer helped us with wording, making sure the rules were consistent.
  • Herb Sutter helped ensure that lookup rules were sane from a programmer’s point of view.

Using namespaces and operator==(), you can (today) construct programs for which a==b is true in one place and false in another. That’s unavoidable if you treat == as an ordinary function. But == is not ordinary! Its semantics is fixed by the rules of logic (we cannot have both a==b and a!=b), and its meaning must match that of copying (e.g., after a=b we must have a==b). Secondly, slicing is evil. Defining = in terms of references was a mistake. As far as I can remember, this is the only place in C++ where I made a change based solely on the advice of a theoretician: “OO is based on references, so for uniformity == should be based on references.” But there is nothing OO about ==! Each class (in a hierarchy or not) has its own ==, just like it has its own =. You can define “odd” assignments and comparisons yourself. That’s your problem, but the default must be sane and safe.

Jens suggested the obvious solution: just ban slicing for both == and =. I had shied away from this incompatible change, but the result is beautiful. If the committee approves, we have a coherent set of rules and we eliminate some subtle nasty bugs! To preserve the techniques of tag dispatching, the rule is that you cannot slice if the derived class has added a non-static data member. That is, the derived to base conversion works unless it produces a sliced object.