<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>

  <meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<!-- This should replace the style block once it is published somewhere accessible
  <link href="../../base_www/style.hinc" rel="stylesheet" type="text/css" />
-->

  <style type="text/css">

    body { color: #000000; background-color: #FFFFFF; }
    del { text-decoration: line-through; color: #8B0040; }
    ins { text-decoration: underline; color: #005100; }

    p.example { margin-left: 2em; }
    pre.example { margin-left: 2em; }
    div.example { margin-left: 2em; }

    code.extract { background-color: #F5F6A2; }
    pre.extract { margin-left: 2em; background-color: #F5F6A2;
      border: 1px solid #E1E28E; }

    p.function { }
    .attribute { margin-left: 2em; }
    .attribute dt { float: left; font-style: italic;
      padding-right: 1ex; }
    .attribute dd { margin-left: 0em; }

    blockquote.std { color: #000000; background-color: #F1F1F1;
      border: 1px solid #D1D1D1;
      padding-left: 0.5em; padding-right: 0.5em; }
    blockquote.stddel { text-decoration: line-through;
      color: #000000; background-color: #FFEBFF;
      border: 1px solid #ECD7EC;
      padding-left: 0.5empadding-right: 0.5em; ; }

    blockquote.stdins { text-decoration: underline;
      color: #000000; background-color: #C8FFC8;
      border: 1px solid #B3EBB3; padding: 0.5em; }

    table { border: 1px solid black; border-spacing: 0px;
      margin-left: auto; margin-right: auto; }
    th { text-align: left; vertical-align: top;
      padding-left: 0.8em; border: none; }
    td { text-align: left; vertical-align: top;
      padding-left: 0.8em; border: none; }

    table.docinfo { border: none; border-spacing: 0px;
      margin-left: auto; margin-right: none; float: right; }

  </style>

  <title>Flexible static_assert messages</title>

</head>

<body>
  <table border="1" class="docinfo">
    <tr> <th>Doc. No.:</th> <td>N4433</td> </tr>
    <tr> <th>Date:</th>     <td>2014-04-09</td> </tr>
    <tr> <th>Project:</th>  <td>Programming Language C++, Evolution Working Group</td> </tr>
    <tr> <th>Reply To:</th> <td>Michael Price<br/>
                                &lt;<a href="mailto:michael.b.price.dev@gmail.com">michael.b.price.dev@gmail.com</a>&gt;</td> </tr>
  </table>

  <br/>
  <h1>Flexible <code>static_assert</code> messages</h1>

  <h2><a name="introduction">I. Introduction</a></h2>

  <p>
    Currently, the specification for <code>static_assert</code> has two forms,
    one that takes a <em>string-literal</em> that is used as a diagnostic
    message and another that takes no diagnostic message at all. The
    restriction that the diagnostic message be a <em>string-literal</em> is
    limiting since it doesn't allow useful contextual information to be
    inserted into the diagnostic message.  This paper proposes that we change
    the specification to take a constant expression that can be contextually
    converted to a <code>const char*</code>, <code>const wchar_t*</code>,
    <code>const char16_t*</code>, or <code>const char32_t*</code> instead of a
    <em>string-literal</em>.
  </p>

  <h2><a name="motivation">II. Motivation</a></h2>

  <p>
    As a library developer, I'd like to include information in diagnostic
    messages that indicate that my library was the source of the assertion.
    With the current specification, this becomes an error-prone exercise. If
    I were required to "rebrand" my library, it's even worse. With the
    proposed changes, it's a matter of changing a single line in a header
    file.
  </p>

  <pre class="example">
  <code>// mplib.h
  //
  constexpr auto libraryTag = "MP"S; // Presumes a UDL for compile-time string literals
                                     // (see N4121 <a href="#ref_2">[2]</a>)

  template &lt;typename C, typename M&gt;
  constexpr auto msg (C errorCode, M message)
  {
      return libraryTag + errorCode + ": "S + message;
  }


  // mpsource1.cpp
  //
  #include "mplib.h"
  // ...
  static_assert(sizeof(int) == 32, msg("001"S, "Requires type 'int' to be 32 bits"S));


  // mpsource8534.cpp
  //
  #include "mplib.h"
  // ...
  static_assert(std::is_integral&lt;T&gt;::value, msg("999"S, "T must be an integral type"S);</code>
  </pre>

  <p>
    Another use case of such an extension would be to allow type-dependent or
    implementation-specific information to appear in the diagnostic message.
  </p>

  <pre class="example">
  <code>// Assume some compile-time formatter function with the following syntax
  //
  template &lt;typename M, typename Ts...&gt;
  constexpr auto format (const M&amp; message, Ts... ts);


  template &lt;typename T, std::size_t N&gt;
  struct limited_buffer {
    unsigned char data[16];

    static_assert(sizeof(T) * N &lt;= sizeof(data),
                  format("You can only fit {0} {1}s into a {2}."S,
                         sizeof(data)/sizeof(T),
                         typeid(T)::name(),    // Assuming this were constexpr
                         "limited_buffer"S
                        )
                 );
  };</code>
  </pre>

  <h2><a name="specification">III. Technical Specification</a></h2>

  <p>
    All edits are against N4140 <a href="#ref_1">[1]</a>
  </p>

  <p>
    Edit paragraph 7.1 [dcl.dcl] as follows.
  </p>

  <blockquote class="std"><p>
    <div style="text-indent:-2em; margin-left:2em;">
      <em>static_assert-declaration:</em><br/>
      <code>static_assert ( <del><em>constant-expression</em></del> <ins><em>constant-expression-test</em></ins> ) ;</code><br/>
      <code>static_assert ( <del><em>constant-expression</em></del> <ins><em>constant-expression-test</em></ins> , <del><em>string-literal</em></del><ins><em>constant-expression-message</em></ins> ) ;</code>
    </div>
  </p></blockquote>

  <p>
    Edit paragraph 7.1.6 as follows.
  </p>

  <blockquote class="std"><p>
    In a <em>static_assert-declaration</em> the <del><em>constant-expression</em></del>
    <ins><em>constant-expression-test</em></ins> shall be a constant expression
    (5.20) that can be contextually converted to <code>bool</code> (Clause 4)
    <ins>, and the <em>constant-expression-message</em> shall be a constant
    expression (5.20) that can be contextually converted to
    <code>const char*</code>, <code>const wchar_t*</code>,
    <code>const char16_t*</code>, or <code>const char32_t*</code>
    (Clause 4)</ins>. If the value of <del>the expression</del>
    <ins><em>constant-expression-test</em></ins> when so converted is
    <code>true</code>, the declaration has no effect. Otherwise, the program
    is ill-formed, and the resulting diagnostic message (1.4) shall include
    the <del>text of the <em>string-literal</em></del> <ins>value of
    <em>constant-expression-message</em> after conversion</ins>, if one is
    supplied, except that characters not in the basic source character set
    (2.3) are not required to appear in the diagnostic message.
    [ <em>Example:</em>
    <div style="margin-left:2em; margin-top:1em; margin-bottom:1em;">
      <code>static_assert(sizeof(long) &gt;= 8, "64-bit code generation required for this library.");</code>
    </div>
    <em>&mdash; end example</em> ]
  </p></blockquote>

  <h2><a name="qna">IV. Questions and Answers</a></h2>

  <div style="margin-left: 1.5em;">
    <span style="font-size: 1.15em; font-weight: bold; font-style: italic;">
      Q: What happens if a <code>static_assert</code> fires during the
      evaluation of the <em>constant-expression-message</em>?
    </span>
    &nbsp;
    <span style="font-size: 1.15em;">
      A: Implementation defined behavior.
    </span>
    <p>
      The current text does not specify what happens if a <code>static_assert</code>
      fires during the evaluation of the expression being tested. Admittedly,
      choosing a behavior might be more complicated in this case, but it should
      still be at the discretion of the implementation.
    </p>
  </div>

  <div style="margin-left: 1.5em;">
    <span style="font-size: 1.15em; font-weight: bold; font-style: italic;">
      Q: Why support so many character-types (<code>const wchar_t*</code>, etc...)?
    </span>
    &nbsp;
    <span style="font-size: 1.15em;">
      A: Because the grammer for the existing <em>string-literal</em> parameter does.
    </span>
    <p>
      See [lex.string] <a href="#ref_1">[1]</a>.
    </p>
  </div>

  <h2><a name="acknowledgements">V. Acknowledgements</a></h2>

  <p>
    I would hardly have the time to author these proposals were it not for the
    generosity of my employer, Lexmark International, who has earned my thanks
    for their continuing support. I also wanted to extend my gratitude to those
    individuals who carefully reviewed this paper and provided valuable
    feedback, Chris Sammis, Ryan Lucchese, and John Drouhard.
  </p>

  <h2><a name="references">VI. References</a></h2>

  <a name="ref_1" />
  <div>[1] <a href="http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n4140.pdf">R. Smith, <em>Working Draft, Standard for Programming Language C++</em>. N4140.</a></div>
  <a name="ref_2" />
  <div>[2] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf">A. Tomazos, <em>Compile-Time String: std::string_literal&lt;n&gt;</em>. N4121.</a></div>


</body>
</html>
