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 forflag_isoc17
or any options for
compatibility warnings; however, there is a new__STDC_VERSION__
value, so new cpplib languagesCLK_GNUC17
andCLK_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 asC18
, 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 anint
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]]
onnamespace
s andenum { 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 stringno
throw
unlessthrow()
, andthrow()
isnoexcept(true)
.
Cleaner multi-return and flow control
Structured bindings
Basically, first-class
std::tie
withauto
Example:
*const auto [it, inserted] = map.insert( {"foo", bar} );
* Creates variablesit
andinserted
with deduced type from thepair
thatmap::insert
returns.Works with tuple/pair-likes &
std::array
s and relatively flat structsActually named structured bindings in standard
if (init; condition)
andswitch (init; condition)
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
Extends the
if(decl)
to cases wheredecl
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 constructionis_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 callFoo
withArgs...
and get something compatible withR
", whereR=void
is default.invoke_result<Foo, Args...>
isstd::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]
fstream
s can be opened withpath
s, as well as withconst 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.
- Saves some
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
- Polymorphic allocator, like
std::sample
, sampling from a range?
Container Improvements
try_emplace
andinsert_or_assign
- gives better guarantees in some cases where spurious move/copy would be bad
Splicing for
map<>
,unordered_map<>
,set<>
, andunordered_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
- like
Minimal incomplete type support in containers
Contiguous iterator "concept"
constexpr
iteratorsThe
emplace
family of functions now returns a reference to the created object.
Smart pointer changes
unique_ptr<T[]>
fixes and otherunique_ptr
tweaks.weak_from_this
and some fixed to shared from this
Other std
datatype improvements:
{}
construction ofstd::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 librariesdestroy(_at|_n)
,uninitialized_move(_n)
,uninitialized_value_construct(_n)
,uninitialized_default_construct(_n)
utility code already in most
std
implementations exposedSpecial math functions
scientists may like them
std::clamp()
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
roughly
gcd
andlcm
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 variablesstd::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
- like
std::chrono
polishstd::conjunction
,std::disjunction
,std::negation
exposedstd::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(breaks ABI of some compilers due to name mangling, removed.)std::less
.memory_order_consume
, added language to prefer use ofmemory_order_acquire
Traits
- swap
- is_aggregate
- has_unique_object_representations
Deprecated
- Some C libraries,
<codecvt>
result_of
, replaced withinvoke_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 usebool 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 anint
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]]
onnamespace
s andenum { 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 stringno
throw
unlessthrow()
, andthrow()
isnoexcept(true)
.
Cleaner multi-return and flow control
Structured bindings
Basically, first-class
std::tie
withauto
Example:
*const auto [it, inserted] = map.insert( {"foo", bar} );
* Creates variablesit
andinserted
with deduced type from thepair
thatmap::insert
returns.Works with tuple/pair-likes &
std::array
s and relatively flat structsActually named structured bindings in standard
if (init; condition)
andswitch (init; condition)
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
Extends the
if(decl)
to cases wheredecl
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 constructionis_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 callFoo
withArgs...
and get something compatible withR
", whereR=void
is default.invoke_result<Foo, Args...>
isstd::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]
fstream
s can be opened withpath
s, as well as withconst 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.
- Saves some
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
- Polymorphic allocator, like
std::sample
, sampling from a range?
Container Improvements
try_emplace
andinsert_or_assign
- gives better guarantees in some cases where spurious move/copy would be bad
Splicing for
map<>
,unordered_map<>
,set<>
, andunordered_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
- like
Minimal incomplete type support in containers
Contiguous iterator "concept"
constexpr
iteratorsThe
emplace
family of functions now returns a reference to the created object.
Smart pointer changes
unique_ptr<T[]>
fixes and otherunique_ptr
tweaks.weak_from_this
and some fixed to shared from this
Other std
datatype improvements:
{}
construction ofstd::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 librariesdestroy(_at|_n)
,uninitialized_move(_n)
,uninitialized_value_construct(_n)
,uninitialized_default_construct(_n)
utility code already in most
std
implementations exposedSpecial math functions
scientists may like them
std::clamp()
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
roughly
gcd
andlcm
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 variablesstd::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
- like
std::chrono
polish
Related Topics
Can You Remove Elements from a Std::List While Iterating Through It
How to Determine If a String Is a Number With C++
How to Use the Conditional (Ternary) Operator
C++11 Return Value Optimization or Move
Floating Point Division VS Floating Point Multiplication
C++11 Does Not Deduce Type When Std::Function or Lambda Functions Are Involved
How to Make a Http Request With C++
How to Call a Parent Class Function from Derived Class Function
Position of Least Significant Bit That Is Set
Operator Precedence VS Order of Evaluation
What Happens If I Assign a Negative Value to an Unsigned Variable
What Is the Purpose of the Most Vexing Parse
How to Pass a Unique_Ptr Argument to a Constructor or a Function
Multithreading Program Stuck in Optimized Mode But Runs Normally in -O0
What Are the Complexity Guarantees of the Standard Containers