What Are the New Features in C++17

What is C17 and what changes have been made to the language?

According to GCC reference, C17 is actually a bug-fix version of the C11 standard with DR resolutions integrated.

C17, a bug-fix version of the C11 standard with DR [Defect Report] resolutions
integrated
, will soon go to ballot. This patch adds corresponding
options -std=c17, -std=gnu17 (new default version, replacing
-std=gnu11 as the default), -std=iso9899:2017. As a bug-fix version
of the standard, there is no need for flag_isoc17 or any options for
compatibility warnings; however, there is a new __STDC_VERSION__
value, so new cpplib languages CLK_GNUC17 and CLK_STDC17 are added to
support using that new value with the new options. (If the standard
ends up being published in 2018 and being known as C18, option aliases
can be added. Note however that -std=iso9899:199409 corresponds to a
__STDC_VERSION__ value rather than a publication date.)

(There are a couple of DR resolutions needing implementing in GCC, but
that's independent of the new options.)

So, there are no new features included in C17.

The Cppreference (History of C) says:

Future development

C17 Next minor C language standard revision, will include all accepted C11 defect reports, but no new features.

UPDATE:

  • 2018: C17 (ISO/IEC 9899:2018) (ISO Store) (Final draft) Includes the deprecation of ATOMIC_VAR_INIT and the fixes to the
    following defect reports:

[DR 400], [DR 401], [DR 402], [DR 403],
[DR 404], [DR 405], [DR 406], [DR 407],
[DR 410], [DR 412], [DR 414], [DR 415],
[DR 416], [DR 417], [DR 419], [DR 423],
[DR 426], [DR 428], [DR 429], [DR 430],
[DR 431], [DR 433], [DR 434], [DR 436],
[DR 437], [DR 438], [DR 439], [DR 441],
[DR 444], [DR 445], [DR 447], [DR 448],
[DR 450], [DR 452], [DR 453], [DR 457],
[DR 458], [DR 459], [DR 460], [DR 462],
[DR 464], [DR 465], [DR 468], [DR 470],
[DR 471], [DR 472], [DR 473], [DR 475],
[DR 477], [DR 480], [DR 481], [DR 485],
[DR 487], [DR 491]

What are the new features in C++17?

Language features:

Templates and Generic Code

  • Template argument deduction for class templates

    • Like how functions deduce template arguments, now constructors can deduce the template arguments of the class
    • http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
  • template <auto>

    • Represents a value of any (non-type template argument) type.
  • Non-type template arguments fixes

  • template<template<class...>typename bob> struct foo {}

  • ( Folding + ... + expressions ) and Revisions

  • auto x{8}; is an int

  • modernizing using with ... and lists

Lambda

  • constexpr lambdas

    • Lambdas are implicitly constexpr if they qualify
  • Capturing *this in lambdas

    • [*this]{ std::cout << could << " be " << useful << '\n'; }

Attributes

  • [[fallthrough]], [[nodiscard]], [[maybe_unused]] attributes

  • [[attributes]] on namespaces and enum { erator[[s]] }

  • using in attributes to avoid having to repeat an attribute namespace.

  • Compilers are now required to ignore non-standard attributes they don't recognize.

    • The C++14 wording allowed compilers to reject unknown scoped attributes.

Syntax cleanup

  • Inline variables

  • Like inline functions

  • Compiler picks where the instance is instantiated

  • Deprecate static constexpr redeclaration, now implicitly inline.

  • namespace A::B

  • Simple static_assert(expression); with no string

  • no throw unless throw(), and throw() is noexcept(true).

Cleaner multi-return and flow control

  • Structured bindings

  • Basically, first-class std::tie with auto

  • Example:
    * const auto [it, inserted] = map.insert( {"foo", bar} );
    * Creates variables it and inserted with deduced type from the pair that map::insert returns.

  • Works with tuple/pair-likes & std::arrays and relatively flat structs

  • Actually named structured bindings in standard

  • if (init; condition) and switch (init; condition)

  • if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)

  • Extends the if(decl) to cases where decl isn't convertible-to-bool sensibly.

  • Generalizing range-based for loops

    • Appears to be mostly support for sentinels, or end iterators that are not the same type as begin iterators, which helps with null-terminated loops and the like.
  • if constexpr

  • Much requested feature to simplify almost-generic code.

Misc

  • Hexadecimal float point literals

  • Dynamic memory allocation for over-aligned data

  • Guaranteed copy elision

    • Finally!
    • Not in all cases, but distinguishes syntax where you are "just creating something" that was called elision, from "genuine elision".
  • Fixed order-of-evaluation for (some) expressions with some modifications

    • Not including function arguments, but function argument evaluation interleaving now banned
    • Makes a bunch of broken code work mostly, and makes .then on future work.
  • Direct list-initialization of enums

  • Forward progress guarantees (FPG) (also, FPGs for parallel algorithms)

  • I think this is saying "the implementation may not stall threads forever"?

  • u8'U', u8'T', u8'F', u8'8' character literals (string already existed)

  • "noexcept" in the type system

  • __has_include

    • Test if a header file include would be an error
    • makes migrating from experimental to std almost seamless
  • Arrays of pointer conversion fixes

  • inherited constructors fixes to some corner cases (see P0136R0 for examples of behavior changes)

  • aggregate initialization with inheritance.

  • std::launder, type punning, etc

Library additions:

Data types

  • std::variant<Ts...>

  • Almost-always non-empty last I checked?

  • Tagged union type

  • {awesome|useful}

  • std::optional

    • Maybe holds one of something
    • Ridiculously useful
  • std::any

    • Holds one of anything (that is copyable)
  • std::string_view

    • std::string like reference-to-character-array or substring
    • Never take a string const& again. Also can make parsing a bajillion times faster.
    • "hello world"sv
    • constexpr char_traits
  • std::byte off more than they could chew.

    • Neither an integer nor a character, just data

Invoke stuff

  • std::invoke

    • Call any callable (function pointer, function, member pointer) with one syntax. From the standard INVOKE concept.
  • std::apply

    • Takes a function-like and a tuple, and unpacks the tuple into the call.
  • std::make_from_tuple, std::apply applied to object construction

  • is_invocable, is_invocable_r, invoke_result

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0077r2.html

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html

  • Deprecates result_of

  • is_invocable<Foo(Args...), R> is "can you call Foo with Args... and get something compatible with R", where R=void is default.

  • invoke_result<Foo, Args...> is std::result_of_t<Foo(Args...)> but apparently less confusing?

File System TS v1

  • [class.path]

  • [class.filesystem.error]

  • [class.file_status]

  • [class.directory_entry]

  • [class.directory_iterator] and [class.recursive_directory_iterator]

  • [fs.ops.funcs]

  • fstreams can be opened with paths, as well as with const path::value_type* strings.

New algorithms

  • for_each_n

  • reduce

  • transform_reduce

  • exclusive_scan

  • inclusive_scan

  • transform_exclusive_scan

  • transform_inclusive_scan

  • Added for threading purposes, exposed even if you aren't using them threaded

Threading

  • std::shared_mutex

    • Untimed, which can be more efficient if you don't need it.
  • atomic<T>::is_always_lockfree

  • scoped_lock<Mutexes...>

    • Saves some std::lock pain when locking more than one mutex at a time.
  • Parallelism TS v1

    • The linked paper from 2014, may be out of date
    • Parallel versions of std algorithms, and related machinery
  • hardware_*_interference_size

(parts of) Library Fundamentals TS v1 not covered above or below

  • [func.searchers] and [alg.search]

    • A searching algorithm and techniques
  • [pmr]

    • Polymorphic allocator, like std::function for allocators
    • And some standard memory resources to go with it.
    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
  • std::sample, sampling from a range?

Container Improvements

  • try_emplace and insert_or_assign

    • gives better guarantees in some cases where spurious move/copy would be bad
  • Splicing for map<>, unordered_map<>, set<>, and unordered_set<>

    • Move nodes between containers cheaply.
    • Merge whole containers cheaply.
  • non-const .data() for string.

  • non-member std::size, std::empty, std::data

    • like std::begin/end
  • Minimal incomplete type support in containers

  • Contiguous iterator "concept"

  • constexpr iterators

  • The emplace family of functions now returns a reference to the created object.

Smart pointer changes

  • unique_ptr<T[]> fixes and other unique_ptr tweaks.
  • weak_from_this and some fixed to shared from this

Other std datatype improvements:

  • {} construction of std::tuple and other improvements
  • TriviallyCopyable reference_wrapper, can be performance boost

Misc

  • C++17 library is based on C11 instead of C99

  • Reserved std[0-9]+ for future standard libraries

  • destroy(_at|_n), uninitialized_move(_n), uninitialized_value_construct(_n), uninitialized_default_construct(_n)

  • utility code already in most std implementations exposed

  • Special math functions

  • scientists may like them

  • std::clamp()

    • std::clamp( a, b, c ) == std::max( b, std::min( a, c ) ) roughly
  • gcd and lcm

  • std::uncaught_exceptions

    • Required if you want to only throw if safe from destructors
  • std::as_const

  • std::bool_constant

  • A whole bunch of _v template variables

  • std::void_t<T>

    • Surprisingly useful when writing templates
  • std::owner_less<void>

    • like std::less<void>, but for smart pointers to sort based on contents
  • std::chrono polish

  • std::conjunction, std::disjunction, std::negation exposed

  • std::not_fn

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html

  • Rules for noexcept within std

  • std::is_contiguous_layout, useful for efficient hashing

  • std::to_chars/std::from_chars, high performance, locale agnostic number conversion; finally a way to serialize/deserialize to human readable formats (JSON & co)

  • std::default_order, indirection over std::less. (breaks ABI of some compilers due to name mangling, removed.)

  • memory_order_consume, added language to prefer use of memory_order_acquire

Traits

  • swap
  • is_aggregate
  • has_unique_object_representations

Deprecated

  • Some C libraries,
  • <codecvt>
  • result_of, replaced with invoke_result
  • shared_ptr::unique, it isn't very threadsafe

Isocpp.org has has an independent list of changes since C++14; it has been partly pillaged.

Naturally TS work continues in parallel, so there are some TS that are not-quite-ripe that will have to wait for the next iteration. The target for the next iteration is C++20 as previously planned, not C++19 as some rumors implied. C++1O has been avoided.

Initial list taken from this reddit post and this reddit post, with links added via googling or from the above isocpp.org page.

Additional entries pillaged from SD-6 feature-test list.

clang's feature list and library feature list are next to be pillaged. This doesn't seem to be reliable, as it is C++1z, not C++17.

these slides had some features missing elsewhere.

While "what was removed" was not asked, here is a short list of a few things ((mostly?) previous deprecated) that are removed in C++17 from C++:

Removed:

  • register, keyword reserved for future use
  • bool b; ++b;
  • trigraphs
    • if you still need them, they are now part of your source file encoding, not part of language
  • ios aliases
  • auto_ptr, old <functional> stuff, random_shuffle
  • allocators in std::function

There were rewordings. I am unsure if these have any impact on code, or if they are just cleanups in the standard:

Papers not yet integrated into above:

  • P0505R0 (constexpr chrono)

  • P0418R2 (atomic tweaks)

  • P0512R0 (template argument deduction tweaks)

  • P0490R0 (structured binding tweaks)

  • P0513R0 (changes to std::hash)

  • P0502R0 (parallel exceptions)

  • P0509R1 (updating restrictions on exception handling)

  • P0012R1 (make exception specifications be part of the type system)

  • P0510R0 (restrictions on variants)

  • P0504R0 (tags for optional/variant/any)

  • P0497R0 (shared ptr tweaks)

  • P0508R0 (structured bindings node handles)

  • P0521R0 (shared pointer use count and unique changes?)

Spec changes:

  • exception specs and throw expressions

Further reference:

  • papers grouped by year; not all accepted

  • https://isocpp.org/files/papers/p0636r0.html

    • Should be updated to "Modifications to existing features" here.

Is C++17 based on C17?

Is C++17 based on C17?

No.

The normative reference for C++ as of the current working draft is C11.

If it is C11 now, then it was at latest C11 for C++17. /p>

Here's a related proposal (though I'm not sure that it was exactly this proposal that was adopted).


I have noticed that many of the features new in C++17 were from C17.

I haven't. I haven't compared the two. If similar features were added to both, that's likely a co-incidence. However, since C17 was really just a "bug fix" update to C11, it seems unlikely.

Is there any relation between the two standards?

Not really, no. The two working groups will talk to each other, of course, but the two languages are independent.

Are there any practical differences between the C functions and their C++ equivalents?

Without specific examples I couldn't say, but again you should consider these to be separate and independent things.

C++ is only "based on" C in terms of the library and language features that it "inherits". However, note that this is not a wholesale import of C11 into C++17; that's not how it works.


By the way, although the term "C17" is an accepted (and widespread) name for it, and although its __STDC_VERSION__ macro is 201710L, it's really "C18" (and technically ISO/IEC 9899:2018).

(c.f. C++98's __cplusplus is 199711L; that's just how the timings work out sometimes, when publication stretches just slightly into a subsequent year after things like that have been agreed and frozen.)

What has changed in C++17 in terms of MOVE elision

Since C++17 mandatory elision of copy/move operations was introduced:

Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible:

  • ...

  • In the initialization of an object, when the initializer expression is
    a prvalue of the same class type (ignoring cv-qualification) as the
    variable type:

    T x = T(T(f())); // only one call to default constructor of T, to initialize x

In the initialization of the parameter cp from the prvalue NonCopyable(), the move construction is required to be elided. Note that mandatory copy elision works for both copy operation and move operation.

What are the new features in C++17?

Language features:

Templates and Generic Code

  • Template argument deduction for class templates

    • Like how functions deduce template arguments, now constructors can deduce the template arguments of the class
    • http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
  • template <auto>

    • Represents a value of any (non-type template argument) type.
  • Non-type template arguments fixes

  • template<template<class...>typename bob> struct foo {}

  • ( Folding + ... + expressions ) and Revisions

  • auto x{8}; is an int

  • modernizing using with ... and lists

Lambda

  • constexpr lambdas

    • Lambdas are implicitly constexpr if they qualify
  • Capturing *this in lambdas

    • [*this]{ std::cout << could << " be " << useful << '\n'; }

Attributes

  • [[fallthrough]], [[nodiscard]], [[maybe_unused]] attributes

  • [[attributes]] on namespaces and enum { erator[[s]] }

  • using in attributes to avoid having to repeat an attribute namespace.

  • Compilers are now required to ignore non-standard attributes they don't recognize.

    • The C++14 wording allowed compilers to reject unknown scoped attributes.

Syntax cleanup

  • Inline variables

  • Like inline functions

  • Compiler picks where the instance is instantiated

  • Deprecate static constexpr redeclaration, now implicitly inline.

  • namespace A::B

  • Simple static_assert(expression); with no string

  • no throw unless throw(), and throw() is noexcept(true).

Cleaner multi-return and flow control

  • Structured bindings

  • Basically, first-class std::tie with auto

  • Example:
    * const auto [it, inserted] = map.insert( {"foo", bar} );
    * Creates variables it and inserted with deduced type from the pair that map::insert returns.

  • Works with tuple/pair-likes & std::arrays and relatively flat structs

  • Actually named structured bindings in standard

  • if (init; condition) and switch (init; condition)

  • if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)

  • Extends the if(decl) to cases where decl isn't convertible-to-bool sensibly.

  • Generalizing range-based for loops

    • Appears to be mostly support for sentinels, or end iterators that are not the same type as begin iterators, which helps with null-terminated loops and the like.
  • if constexpr

  • Much requested feature to simplify almost-generic code.

Misc

  • Hexadecimal float point literals

  • Dynamic memory allocation for over-aligned data

  • Guaranteed copy elision

    • Finally!
    • Not in all cases, but distinguishes syntax where you are "just creating something" that was called elision, from "genuine elision".
  • Fixed order-of-evaluation for (some) expressions with some modifications

    • Not including function arguments, but function argument evaluation interleaving now banned
    • Makes a bunch of broken code work mostly, and makes .then on future work.
  • Direct list-initialization of enums

  • Forward progress guarantees (FPG) (also, FPGs for parallel algorithms)

  • I think this is saying "the implementation may not stall threads forever"?

  • u8'U', u8'T', u8'F', u8'8' character literals (string already existed)

  • "noexcept" in the type system

  • __has_include

    • Test if a header file include would be an error
    • makes migrating from experimental to std almost seamless
  • Arrays of pointer conversion fixes

  • inherited constructors fixes to some corner cases (see P0136R0 for examples of behavior changes)

  • aggregate initialization with inheritance.

  • std::launder, type punning, etc

Library additions:

Data types

  • std::variant<Ts...>

  • Almost-always non-empty last I checked?

  • Tagged union type

  • {awesome|useful}

  • std::optional

    • Maybe holds one of something
    • Ridiculously useful
  • std::any

    • Holds one of anything (that is copyable)
  • std::string_view

    • std::string like reference-to-character-array or substring
    • Never take a string const& again. Also can make parsing a bajillion times faster.
    • "hello world"sv
    • constexpr char_traits
  • std::byte off more than they could chew.

    • Neither an integer nor a character, just data

Invoke stuff

  • std::invoke

    • Call any callable (function pointer, function, member pointer) with one syntax. From the standard INVOKE concept.
  • std::apply

    • Takes a function-like and a tuple, and unpacks the tuple into the call.
  • std::make_from_tuple, std::apply applied to object construction

  • is_invocable, is_invocable_r, invoke_result

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0077r2.html

  • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html

  • Deprecates result_of

  • is_invocable<Foo(Args...), R> is "can you call Foo with Args... and get something compatible with R", where R=void is default.

  • invoke_result<Foo, Args...> is std::result_of_t<Foo(Args...)> but apparently less confusing?

File System TS v1

  • [class.path]

  • [class.filesystem.error]

  • [class.file_status]

  • [class.directory_entry]

  • [class.directory_iterator] and [class.recursive_directory_iterator]

  • [fs.ops.funcs]

  • fstreams can be opened with paths, as well as with const path::value_type* strings.

New algorithms

  • for_each_n

  • reduce

  • transform_reduce

  • exclusive_scan

  • inclusive_scan

  • transform_exclusive_scan

  • transform_inclusive_scan

  • Added for threading purposes, exposed even if you aren't using them threaded

Threading

  • std::shared_mutex

    • Untimed, which can be more efficient if you don't need it.
  • atomic<T>::is_always_lockfree

  • scoped_lock<Mutexes...>

    • Saves some std::lock pain when locking more than one mutex at a time.
  • Parallelism TS v1

    • The linked paper from 2014, may be out of date
    • Parallel versions of std algorithms, and related machinery
  • hardware_*_interference_size

(parts of) Library Fundamentals TS v1 not covered above or below

  • [func.searchers] and [alg.search]

    • A searching algorithm and techniques
  • [pmr]

    • Polymorphic allocator, like std::function for allocators
    • And some standard memory resources to go with it.
    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
  • std::sample, sampling from a range?

Container Improvements

  • try_emplace and insert_or_assign

    • gives better guarantees in some cases where spurious move/copy would be bad
  • Splicing for map<>, unordered_map<>, set<>, and unordered_set<>

    • Move nodes between containers cheaply.
    • Merge whole containers cheaply.
  • non-const .data() for string.

  • non-member std::size, std::empty, std::data

    • like std::begin/end
  • Minimal incomplete type support in containers

  • Contiguous iterator "concept"

  • constexpr iterators

  • The emplace family of functions now returns a reference to the created object.

Smart pointer changes

  • unique_ptr<T[]> fixes and other unique_ptr tweaks.
  • weak_from_this and some fixed to shared from this

Other std datatype improvements:

  • {} construction of std::tuple and other improvements
  • TriviallyCopyable reference_wrapper, can be performance boost

Misc



Leave a reply



Submit