C++ Papers for Issaquah - Library, Graphics, Networking, Numerics & Undefined Behavior

by Jens Weller

The 4th and last part about the C++ Papers for Issaquah, where the C++ committee meets this week. I already covered the first batch of proposals from the Library subgroup in the previous part, now its all about papers from Library, Graphics, Networking, Numerics and Undefined Behavior. A very diverse part. Also a good right might be the papers for chicago from library, networking and reflection.

Library II

N3873 - Improved insertion interface for unique-key maps

This paper would like to enhance the insertion interface of unique-key maps (std::map, std::unordered_map). The proposal wants to add two new methods:

  • emplace_stable
  • emplace_or_update

emplace_stable does only insert into the map, when the key does not exist. emplace_or_update inserts only if the key does not exist, if it exists it will update the current object (operator=).

N3876 - Convenience Functions to Combine Hash Values

This proposal aims at making it easier to have a better, but not naive hash function for custom types. It proposes the functions hash_val and hash_combine, where a concrete class would call hash_val with all the needed member that should be in the hash as arguments. hash_val and hash_combine would be implemented as a variadic template functions. The hash_combine function is today already defined by boost hash.

N3877 - Centralized Defensive-Programming Support for Narrow Contracts (Revision 3)

This is a very interesting paper about adding more options to the C++ standard for checking certain conditions. New in this revision is that the namespace has been renamed to contract from precondition. The paper uses std::vector and operator[] vs. at(size_t) as an example, which I think is a very good one. The standard offers with both two different interfaces, the first being narrow (most efficient) and the second being wide (most safe):

  • operator[]
  1. Has a narrow contract
  2. Which means, only the range of 0 - (size-1) is in the bounds of defined behavior, every thing else is undefined.
  3. In practice, operator[] will not check for you, if your index is valid
  • at(size_t)
  1. Has a wide contract
  2. This means, it will test for all side effects. If the argument is out of range, then an exception is thrown.
  3. In practice, at will check your index each call, and is therefore not as fast as operator[], but it will throw if you overreach.

This paper tries now to find a way, to minimize the risk for narrow contracts, to be undefined behavior. The authors suggest to use defensive programming for this, and to extend the Standard Library with the header <contract_assert>. This header shall contain the classes and macros to provide the additional support for C++ in defensive programming. The build mode (safe, debug, release build) then decide, which asserts are executed.

In the example that would mean, that operator[] contains an assert in safe build (all asserts), maybe in debug, and none in release. For more details please read this interesting paper.

N3884 - Contiguous Iterators: A Refinement of Random Access Iterators

Currently, such thing does not exist in the C++ standard, but often it would be good to know, if the memory is contiguous. A contiguous iterator is a special form of a random access iterator, where the following two rules apply:

std::pointer_from(i) == std::addressof(*i) (when i is dereferenceable)
std::pointer_from(i + n) == std::pointer_from(i) + n (when i + n is a valid iterator)

To add full support for this to the standard, some changes are needed. First, a from random_access_iterator_tag derived contiguous_iterator_tag, and changing the tags of std::basic_string, std::array, std::vector and valarray. This would then allow for tag based specialization on contiguous iterators. The paper already includes the necessary wording for the standard changes.

N3887 - Consistent Metafunction Aliases

This paper tries to find a guideline for adding metafunction aliases to the standard. The proposed guideline is:

A class template should be accompanied by a metafunction-name t template alias if it provides a public member type named type and no other accessible members.

The authors did apply this simple rule to the C++14 standard, and found that only tuple_element_t was missing. Hence the authors suggest to add the proposed guideline and tuple_element_t to the standard.

N3890 - Container<Incomplete Type>

This proposal wants to enable incomplete types for structure definitions with STL containers:

struct Entry
{
    std::deque messages;
    // ...
};

A possible approach is to make STL container instantiations well-formed even when some of the template arguments are incomplete types. This will also not break any existing code or language restrictions. This feature is currently already provided by boost::containers and libstdc++. The authors see the following advantages with this solution:

  • The value semantics of value_type is well-preserved
  • scoped allocators work out-of-the-box
  • such a container can be used in type erasure

Currently a sample implementation as a fork of llvms libc++ exists.

N3898 - HASHING AND FINGERPRINTING

This paper deals with hashing types in C++, building up on N3333. The difference is, that this proposal would like to separate the hashing from the hashed values. The author proposes that a hash_value function should return a std::tuple via std::tie, which then could be used for hashing by different hashing and fingerprinting classes. In this way, a custom type would not define the way it should be hashed. Instead it would expose the values to be hashed to one or more hash implementations. The author concludes, that the standard should provide at least the following hasher classes:

  • basic hasher for use in unordered containers and std::hash
  • fingerprint64
  • fingerprint128
  • near_universal60
  • near_universal120

This proposal is similar to N3876, but splits the hash_value from the hashing process, so that the hasher can be reused.

Graphics

Graphics is the newest sub group in the C++ committee, its role is to define an API for 2d drawing. For more background read through the graphics google group.

N3825 - SG13 Graphics Discussion

This paper tries to reflect and give a foundation for further Discussions on the subject. It proposes to possible ways to add a 2d drawing API to the standard:

  • based on an existing standard, like SVG and Canvas
  • based on an existing library, like Cinder, cairo or other libraries

It also discusses the current proposal from this subgroup, such as how to use cairo as a starting point for a 2d drawing API in C++.

N3888 - A Proposal to Add 2D Graphics Rendering and Display to C++

The goal of this proposal is to define a 2D drawing API based on a mechanical transformation of the cairo graphics library . Cairo is a comprehensive, cross - platform, wide ly - used, mature 2D graphics library written in C with an object - oriented style.

So, this paper tries to define a 2d drawing API based on cairo. Where cairo serves as a starting point, as it is written in a very clean and oo like C, and already in wide use in cross platform software such as Mozilla Firefox, GTK+ or Mono. The authors propose now, to transform cairos C API mechanically into a C++ API. This can be achieved by applying a set of well-defined transformation rules.

The alternatives would be to either to create a new API by synthesis of existing 2d APIs or to start from HTML5s canvas API as an existing SVG like standard. The implementers prefer to have cairo as a possible backend, which could be switched by implementers to use more efficient, modern platform rendering.

The paper continues with implementation details of a possible 2D rendering API such as GPU resources and native handles. This paper is a very good and not too detailed take on the effort of defining a possible 2d drawing API for C++.

Networking

N3827 - Working Draft Technical Specification - URI

This is the current draft/technical specification for adding a URI class to the standard library.

Proposed classes are:

  • uri
  • uri_builder
  • uri_error
    • uri_syntax_error
    • uri_builder_error
    • percent_decoding_error

Where uri_error is a strong enum class, the uri class it self refers to its fragments over std::optional<string_view>, the interface is kind of logical (e.g. host, port, query methods).

Numerics

N3864 - A constexpr bitwise operations library for C++

This proposal is a pure library extension, adding support for bitwise operations at compile time through constexpr. The authors propose to add functions supporting constexpr bitwise operations to <cmath> and <memory>, following the two goals of

  • Provide the programmer with better access to the machine
  • Provide a reusable library of generic bitwise manipulation routines

N3871 - Proposal to Add Decimal Floating Point Support to C++ (revision 2)

This proposal would like to add full decimal floating point support to C++ as defined in the Decimal TR published in 2009. Its aim is at the next major revision of C++, so the standard after C++14. The implementation should take advantage of C++11 the author proposes, and that most of the bindings for C++ are already defined in the Decimal TR. Also there are already existing C Implementations from HP, IBM or Intel, which could act as a base and backend for a possible C++ implementation.

Undefined Behavior

N3881 - Fixing the specification of universal-character-names

Universal character names (aka UCNs) are a way to express internationalization in source code without relying on source text encoding. UCNs can be seen as similar to character encoding, the authors see in the current specification of UCNs for the C++ standard two main problems:

  • Undefined behavior is an undesirable kind of specification, because it technically allows the implementation to quietly produce a defective executable file. There is consensus that errors in preprocessor usage should not have runtime consequences. There is even a CERT security advisory about UCNs causing undefined behavior. N3801 "Removing Undefined Behavior from the Preprocessor" directly addresses this by recommending to convert undefined behavior specifications to ill-formedness.
  • There are corner cases which are not specified as undefined behavior. These may be well- defined and misinterpreted, or ill-formed yet undiagnosed, by popular implementations, or simply excessively restrictive. Underspecified cases undermine the effect of N3801 by remaining wrongly defined.

The authors present several corner cases, which are currently not specified (e.g. undefined behavior), and try to work out a solution to fix the specification.

N3882 - An update to the preprocessor specification

C++ inherits the preprocessor from C, part of the preprocessors behavior is to use undefined behavior to specify latitude for implementation differences. Today, there is a consensus on what the preprocessor should do, and such the possibility to remove the undefined behavior inherited from C. The proposal wants to capture the status quo into the standard. The authors conclude that such a consensus can be reached by surveying the  most popular implementations of C++ (MSVC, GCC, Clang 3.4 and EDG/ICC 13). The paper is a detailed analysis of todays preprocessor implementations with the goal to unify their behavior into the standard.

 

Finally the last paper, I will post a follow up in March, as C++14 then hopefully will be on its way.

Go back

Follow Meeting C++

tl_files/mcpp/yt.pngtl_files/mcpp/gplus-50.pngtl_files/mcpp/twitter.pngtl_files/mcpp/facebook.png