<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Mar 2, 2016 at 9:56 AM, William Dillon via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Please see the <a href="https://gist.github.com/hpux735/eafad78108ed42879690" target="_blank">gist</a> for the most up-to-date drafts.</p>

<p>I appreciate any comments, concerns and questions!</p>

<h1>Improve the portability of Swift with differently signed char.</h1>

<ul>
<li>Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/004x-target-specific-chars.md" target="_blank">SE–004x</a></li>
<li>Author: <a href="https://github.com/hpux735" target="_blank">William Dillon</a></li>
<li>Status: <strong>Draft</strong></li>
<li>Review manager: TBD</li>
</ul>

<h2>Introduction</h2>

<p>In C, the signness of <code>char</code> is undefined. A convention is set by either the platform, such as Windows, or by the architecture ABI specification, as is typical on System-V derived systems. A subset of known platforms germane to this discussion and their <code>char</code> signness is provided below.</p>

<table>
<colgroup>
<col style="text-align:center">
<col style="text-align:center">
<col style="text-align:center">
<col style="text-align:center">
<col style="text-align:center">
<col style="text-align:center">
<col style="text-align:center">
</colgroup>

<thead>
<tr>
        <th style="text-align:center">char</th>
        <th style="text-align:center">ARM</th>
        <th style="text-align:center">mips</th>
        <th style="text-align:center">PPC</th>
        <th style="text-align:center">PPC64</th>
        <th style="text-align:center">i386</th>
        <th style="text-align:center">x86_64</th>
</tr>
</thead>

<tbody>
<tr>
        <td style="text-align:center">Linux/ELF</td>
        <td style="text-align:center">unsigned <a href="http://www.eecs.umich.edu/courses/eecs373/readings/ARM-AAPCS-EABI-v2.08.pdf" target="_blank">1</a></td>
        <td style="text-align:center">unsigned <a href="http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf" target="_blank">2</a></td>
        <td style="text-align:center">unsigned <a href="https://uclibc.org/docs/psABI-ppc.pdf" target="_blank">3</a></td>
        <td style="text-align:center">unsigned <a href="http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html" target="_blank">4</a></td>
        <td style="text-align:center">signed <a href="http://www.sco.com/developers/devspecs/abi386-4.pdf" target="_blank">5</a></td>
        <td style="text-align:center">signed <a href="http://www.x86-64.org/documentation/abi.pdf" target="_blank">6</a></td>
</tr>
<tr>
        <td style="text-align:center">Mach-O</td>
        <td style="text-align:center">signed [7]</td>
        <td style="text-align:center">N/A</td>
        <td style="text-align:center">signed [7]</td>
        <td style="text-align:center">signed [7]</td>
        <td style="text-align:center">signed [7]</td>
        <td style="text-align:center">signed [7]</td>
</tr>
<tr>
        <td style="text-align:center">Windows</td>
        <td style="text-align:center">signed [8]</td>
        <td style="text-align:center">signed [8]</td>
        <td style="text-align:center">signed [8]</td>
        <td style="text-align:center">signed [8]</td>
        <td style="text-align:center">signed [8]</td>
        <td style="text-align:center">signed [8]</td>
</tr>
</tbody>
</table>

<p>This is not a great problem in C, and indeed many aren’t even aware of the issue. Part of the reason for this is that C will silently cast many types into other similar types as necessary. Notably, even with <code>-Wall</code> clang produces no warnings while casting beteen any pair of <code>char</code>, <code>unsigned char</code>, <code>signed char</code> and <code>int</code>. Swift, in contrast, does not cast types without explicit direction from the programmer. As implemented, <code>char</code> is interpreted by swift as <code>Int8</code>, regardless of whether the underlying platform uses <code>signed</code> or <code>unsigned char</code>. As every Apple platform (seemingly) uses <code>signed char</code> as a convention, it was an appropriate choice. However, now that Swift is being ported to more and more platforms, it is important that we decide how to handle the alternate case.</p>

<p>The problem at hand may be most simply demonstrated by a small example. Consider a C API where a set of functions return values as <code>char</code>:</p>

<pre><code>char charNegFunction(void)    { return  -1; }
char charBigPosFunction(void) { return 255; }
char charPosFunction(void)    { return   1; }
</code></pre>

<p>Then, if the API is used in C thusly:
<code>C
char negValue = charNegFunction();
char posValue = charPosFunction();
char bigValue = charBigPosFunction();
printf(&quot;From clang: Negative value: %d, positive value: %d, big positive value: %d\n&quot;, negValue, posValue, bigValue);
</code>
You get exactly what you would expect on <code>signed char</code> platforms:
<code>
>From clang: Negative value: -1, positive value: 1, big positive value: -1
</code>
and on <code>unsigned char</code> platforms:
<code>
>From clang: Negative value: 255, positive value: 1, big positive value: 255
</code>
In its current state, swift behaves similarly to C on <code>signed char</code> platforms.
<code>
>From Swift: Negative value: -1, positive value: 1, big positive value: -1
</code></p>

<p>This code is available <a href="https://github.com/hpux735/badCharExample" target="_blank">here</a>, if you would like to play with it yourself.</p>

<h2>Motivation</h2>

<p>The third stated focus area for Swift 3.0 is <strong>portability</strong>, to quote the evolution document:</p>

<blockquote>
<ul>
<li><strong>Portability</strong>: Make Swift available on other platforms and ensure that one can write portable Swift code that works properly on all of those platforms.</li>
</ul>
</blockquote>

<p>As it stands, Swift’s indifference to the signness of <code>char</code> while importing from C can be ignored in many cases. The consequences of inaction, however, leave the door open for extremely subtle and dificult to diagnose bugs any time a C API relies on the use of values greater than 128 on platforms with <code>unsigned char</code>; in this case the current import model certainly violates the Principle of Least Astonishment.</p></div></blockquote><div><br></div><div>It does violate the principle of least astonishment, but we should acknowledge that the implementation-specific nature of C&#39;s char signedness is making code *less* portable, not more -- because the same code can mean different things on different platforms.  Reflecting the same in Swift makes Swift code less portable, too.</div><div><br></div><div>Dmitri</div></div><div><br></div>-- <br><div class="gmail_signature">main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>&gt;*/</div>
</div></div>