<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
        <title>Feature testing: Summary of significant changes to C++14</title>
        <base href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/" />
</head>
<body>
        <table border="1" summary="This table provides identifying information for this document.">
                <tr>
                        <th>Date:</th>
                        <td>2013-05-01</td>
                </tr>
                <tr>
                        <th>Reply to:</th>
                        <td>Clark Nelson</td>
                </tr>
                <tr>
                        <th>Title:</th>
                        <td>Feature testing: Summary of significant changes to C++14</td>
                </tr>
        </table>
        <h1>Feature testing: Summary of significant changes to C++14</h1>
        <h2>Introduction</h2>
        <p>In the transition from C++03 to C++11 &mdash; which of course is ongoing &mdash;
                much pain has been caused by different implementations adding new features in different
                orders.</p>
        <p>For example, variadic templates were added to the working paper for C++11 by N2242,
                adopted by the committee in 2007. They were implemented and released by GNU in 2008.
                EDG implemented them in 2011. Microsoft apparently has yet to implement them.</p>
        <p>On the other hand, <code>decltype</code> was added to the working paper by N2343,
                adopted in 2007. EDG implemented it in 2007, GNU in 2008, and Microsoft by 2010.</p>
        <p>Implementers of portable code, such as Boost, Dinkumware and Plum Hall, are for practical
                purposes obliged to know exactly which features are and are not usable in each implementation
                of interest.</p>
        <p>Today, the only way to do that is to test, in an implementation-specific manner (probably
                using a version-number macro), whether the implementation is new enough to support
                the feature in question &mdash; for each implementation of interest.</p>
        <h2>An example: simultaneously too simple and too complicated</h2>
        <p>Here is some code that attempts to determine whether rvalue references are available
                in the implementation in use:</p>
        <pre>#ifndef __USE_RVALUE_REFERENCES
  #if (__GNUC__ > 4 || __GNUC__ == 4 &amp;&amp; __GNUC_MINOR__ >= 3) || \
      _MSC_VER >= 1600
    #if __EDG_VERSION__ > 0
      #define __USE_RVALUE_REFERENCES (__EDG_VERSION__ >= 410)
    #else
      #define __USE_RVALUE_REFERENCES 1
    #endif
  #elif __clang__
    #define __USE_RVALUE_REFERENCES __has_feature(cxx_rvalue_references)
  #else
    #define __USE_RVALUE_REFERENCES 0
  #endif
#endif</pre>
        <p>First, the GNU and Microsoft version numbers are checked to see if they are high
                enough. But then a check is made of the EDG version number, since that front end
                also has compatibility modes for both those compilers, and defines macros indicating
                (claimed) compatibility with them. If the feature wasn't implemented in the indicated
                EDG version, it is assumed that the feature is not available &mdash; even though
                it is possible for a customer of EDG to implement a feature before EDG does.</p>
        <p>Fortunately Clang has ways to test specifically for the presence of specific features.
                But unfortunately, the function-call-like syntax used for such tests won't work
                with a standard preprocessor, so this fine new feature winds up adding its own flavor
                of complexity to the mix.</p>
        <p>Also note that this code effectively assumes that the IBM and Oracle compilers do
                not implement rvalue references at all. That should not be interpreted as a slight
                to those compilers; it's just that this code has already gotten pretty complicated
                even before taking them into account.</p>
        <p>Also note that this code doesn't check to see if any required command-line option
                has been thrown to enable support for the feature in question, so it will get the
                wrong answer in many cases.</p>
        <table border="1">
                <thead>
                        <tr>
                                <th colspan="6">Significant changes to C++14</th>
                        </tr>
                        <tr>
                                <th>Doc. No.</th>
                                <th>Title</th>
                                <th>Primary Section</th>
                                <th>Macro</th>
                                <th>Value</th>
                                <th>Header</th>
                        </tr>
                </thead>
                <tbody>
                        <tr>
                                <td><a href="../2012/n3472.pdf">N3472</a></td>
                                <td>Binary Literals in the C++ Core Language</td>
                                <td>2.14</td>
                                <td><code>__cpp_binary_literals</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3323.pdf">N3323</a></td>
                                <td>A Proposal to Tweak Certain C++ Contextual Conversions</td>
                                <td>4</td>
                                <td><code>__cpp_contextual_conversions</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3648.html">N3648</a></td>
                                <td>Wording Changes for Generalized Lambda-capture</td>
                                <td>5.1</td>
                                <td><code>__cpp_generalized_capture</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3649.html">N3649</a></td>
                                <td>Generic (Polymorphic) Lambda Expressions</td>
                                <td>5.1</td>
                                <td><code>__cpp_generic_lambda</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3664.html">N3664</a></td>
                                <td>Clarifying Memory Allocation</td>
                                <td>5.3</td>
                                <td><code>__cpp_new_merging</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3624.html">N3624</a></td>
                                <td>Core Issue 1512: Pointer comparison vs qualification conversions</td>
                                <td>5.9, 5.10</td>
                                <td colspan="3"><em>Core issue fix, not a feature; no macro needed</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3652.html">N3652</a></td>
                                <td>Relaxing constraints on constexpr functions / constexpr member functions and implicit
                                        const</td>
                                <td>5.19, 7.1</td>
                                <td><code>__cpp_relaxed_constexpr</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3638.html">N3638</a></td>
                                <td>Return type deduction for normal functions</td>
                                <td>7.1</td>
                                <td><code>__cpp_return_type_deduction</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3639.html">N3639</a></td>
                                <td>Runtime-sized arrays with automatic storage duration</td>
                                <td>8.3</td>
                                <td><code>__cpp_runtime_array</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3653.html">N3653</a></td>
                                <td>Member initializers and aggregates</td>
                                <td>8.5</td>
                                <td><code>__cpp_aggregate_nsdmi</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3667.html">N3667</a></td>
                                <td>Drafting for Core 1402</td>
                                <td>12.8</td>
                                <td colspan="3"><em>Core issue fix, not a feature; no macro needed</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3651.pdf">N3651</a></td>
                                <td>Variable Templates</td>
                                <td>14, 14.7</td>
                                <td><code>__cpp_variable_templates</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3669.pdf">N3669</a></td>
                                <td>Fixing constexpr member functions without const</td>
                                <td><em>various</em></td>
                                <td colspan="3"><em>Library fix, not a feature; no macro needed</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3673.html">N3673</a></td>
                                <td>C++ Library Working Group Ready Issues Bristol 2013</td>
                                <td><em>various</em></td>
                                <td colspan="3"><em>Library issue fixes, not a feature; no macro needed</em></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3471.html">N3471</a></td>
                                <td>Constexpr Library Additions: utilities</td>
                                <td>20.2-20.4</td>
                                <td rowspan="3"><code>__cpp_lib_constexpr_functions</code></td>
                                <td rowspan="3"></td>
                                <td><code>&lt;utility&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3469.html">N3469</a></td>
                                <td>Constexpr Library Additions: chrono</td>
                                <td>20.11</td>
                                <td><code>&lt;chrono&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3470.html">N3470</a></td>
                                <td>Constexpr Library Additions: containers</td>
                                <td>23.3</td>
                                <td><code>&lt;array&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3658.html">N3658</a></td>
                                <td>Compile-time integer sequences</td>
                                <td>20</td>
                                <td><code>__cpp_lib_integer_sequences</code></td>
                                <td></td>
                                <td><code>&lt;utility&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3668.html">N3668</a></td>
                                <td>exchange() utility function</td>
                                <td>20</td>
                                <td><code>__cpp_lib_exchange_function</code></td>
                                <td></td>
                                <td><code>&lt;utility&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3670.html">N3670</a></td>
                                <td>Wording for Addressing Tuples by Type</td>
                                <td>20.2-20.4</td>
                                <td><code>__cpp_lib_tuples_by_type</code></td>
                                <td></td>
                                <td><code>&lt;utility&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3672.html">N3672</a></td>
                                <td>A proposal to add a utility class to represent optional objects</td>
                                <td>20.5</td>
                                <td><code>__cpp_lib_header_optional</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3656.htm">N3656</a></td>
                                <td>make_unique</td>
                                <td>20.7</td>
                                <td><code>__cpp_lib_make_unique</code></td>
                                <td></td>
                                <td><code>&lt;memory&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3421.htm">N3421</a></td>
                                <td>Making Operator Functors greater&lt;&gt;</td>
                                <td>20.8</td>
                                <td><code>__cpp_lib_operator_functors</code></td>
                                <td></td>
                                <td><code>&lt;functional&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="../2012/n3462.html">N3462</a></td>
                                <td>std::result_of and SFINAE</td>
                                <td>20.9</td>
                                <td><code>__cpp_lib_result_of_sfinae</code></td>
                                <td></td>
                                <td><code>&lt;functional&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3545.pdf">N3545</a></td>
                                <td>An Incremental Improvement to integral_constant</td>
                                <td>20.9</td>
                                <td><code>__cpp_lib_improved_integral_constant</code></td>
                                <td></td>
                                <td><code>&lt;type_traits&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3655.pdf">N3655</a></td>
                                <td>TransformationTraits Redux</td>
                                <td>20.9</td>
                                <td><code>__cpp_lib_transformation_trait_aliases</code></td>
                                <td></td>
                                <td><code>&lt;type_traits&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3642.pdf">N3642</a></td>
                                <td>User-defined Literals for Standard Library Types</td>
                                <td>20.11, 21.7</td>
                                <td><code>__cpp_lib_type_udls</code></td>
                                <td></td>
                                <td><code>&lt;string&gt;</code><br />
                                        <code>&lt;chrono&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3662.html">N3662</a></td>
                                <td>C++ Dynamic Arrays</td>
                                <td>23.2, 23.3</td>
                                <td><code>__cpp_lib_header_dynarray</code></td>
                                <td></td>
                                <td><em>predefined</em></td>
                        </tr>
                        <tr>
                                <td><a href="n3657.htm">N3657</a></td>
                                <td>Adding heterogeneous comparison lookup to associative containers</td>
                                <td>23.4</td>
                                <td><code>__cpp_lib_heterogeneous_comparison</code></td>
                                <td></td>
                                <td><code>&lt;map&gt;</code><br />
                                        <code>&lt;set&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3644.pdf">N3644</a></td>
                                <td>Null Forward Iterators</td>
                                <td>24.2</td>
                                <td><code>__cpp_lib_null_iterators</code></td>
                                <td></td>
                                <td><code>&lt;iterator&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3671.html">N3671</a></td>
                                <td>Making non-modifying sequence operations more robust</td>
                                <td>25.2</td>
                                <td><code>__cpp_lib_robust_sequences</code></td>
                                <td></td>
                                <td><code>&lt;algorithm&gt;</code></td>
                        </tr>
                        <tr>
                                <td><a href="n3654.html">N3654</a></td>
                                <td>Quoted Strings Library Proposal</td>
                                <td>27.7</td>
                                <td><code>__cpp_lib_quoted_string_io</code></td>
                                <td></td>
                                <td><code>&lt;iomanip&gt;</code></td>
                        </tr>
                </tbody>
        </table>
</body>
</html>