[swift-evolution] [proposal]Decouple definition of Int8 from target char type

William Dillon william at housedillon.com
Fri Feb 26 11:01:27 CST 2016


> On Feb 25, 2016, at 11:13 PM, Dmitri Gribenko <gribozavr at gmail.com> wrote:
> 
> On Thu, Feb 25, 2016 at 9:58 PM, William Dillon <william at housedillon.com> wrote:
>>>> Swift currently maps the Int8 type to be equal to the char type of the target platform.  On targets where char is unsigned by default, Int8 becomes an unsigned 8-bit integer, which is a clear violation of the Principle of Least Astonishment.  Furthermore, it is impossible to specify a signed 8-bit integer type on platforms with unsigned chars.
>>> 
>>> I'm probably misunderstanding you, but are you sure that's what is
>>> happening?  I can't imagine how the standard library would just
>>> silently make Int8 unsigned on Linux arm.
>>> 
>> 
>> I think the best way to demonstrate this is through an example.  Here is a sample swift program:
>> 
>> import Foundation
>> print(NSNumber(char: Int8.min).shortValue)
> 
> There is a lot happening in this snippet of code (including importing
> two completely different implementations of Foundation, and the pure
> swift one not being affected by Clang importer at all).  Could you
> provide AST dumps for both platforms for this code?
> 

Of course.  Here’s the AST on ARM:

wdillon at tegra-ubuntu:~$ swiftc -dump-ast example.swift
(source_file
  (import_decl 'Foundation')
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=example.swift:2:1 range=[example.swift:2:1 - line:2:42] nothrow
        (declref_expr type='(Any..., separator: String, terminator: String) -> ()' location=example.swift:2:1 range=[example.swift:2:1 - line:2:1] decl=Swift.(file).print(_:separator:terminator:) specialized=no)
        (tuple_shuffle_expr implicit type='(Any..., separator: String, terminator: String)' location=example.swift:2:32 range=[example.swift:2:6 - line:2:42] sourceIsScalar elements=[-2, -1, -1] variadic_sources=[0]
          (paren_expr type='Any' location=example.swift:2:32 range=[example.swift:2:6 - line:2:42]
            (erasure_expr implicit type='Any' location=example.swift:2:32 range=[example.swift:2:7 - line:2:32]
              (member_ref_expr type='Int16' location=example.swift:2:32 range=[example.swift:2:7 - line:2:32] decl=Foundation.(file).NSNumber.shortValue
                (call_expr type='NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:30] nothrow
                  (constructor_ref_call_expr type='(char: Int8) -> NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] nothrow
                    (declref_expr implicit type='NSNumber.Type -> (char: Int8) -> NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] decl=Foundation.(file).NSNumber.init(char:) specialized=no)
                    (type_expr type='NSNumber.Type' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] typerepr='NSNumber'))
                  (tuple_expr type='(char: Int8)' location=example.swift:2:15 range=[example.swift:2:15 - line:2:30] names=char
                    (member_ref_expr type='Int8' location=example.swift:2:27 range=[example.swift:2:22 - line:2:27] decl=Swift.(file).Int8.min
                      (type_expr type='Int8.Type' location=example.swift:2:22 range=[example.swift:2:22 - line:2:22] typerepr='Int8'))))))))))))

And Darwin:

Falcon:~ wdillon$ xcrun -sdk macosx swiftc -dump-ast example.swift
(source_file
  (import_decl 'Foundation')
  (top_level_code_decl
    (brace_stmt
      (call_expr type='()' location=example.swift:2:1 range=[example.swift:2:1 - line:2:42] nothrow
        (declref_expr type='(Any..., separator: String, terminator: String) -> ()' location=example.swift:2:1 range=[example.swift:2:1 - line:2:1] decl=Swift.(file).print(_:separator:terminator:) specialized=no)
        (tuple_shuffle_expr implicit type='(Any..., separator: String, terminator: String)' location=example.swift:2:32 range=[example.swift:2:6 - line:2:42] sourceIsScalar elements=[-2, -1, -1] variadic_sources=[0]
          (paren_expr type='Any' location=example.swift:2:32 range=[example.swift:2:6 - line:2:42]
            (erasure_expr implicit type='Any' location=example.swift:2:32 range=[example.swift:2:7 - line:2:32]
              (member_ref_expr type='Int16' location=example.swift:2:32 range=[example.swift:2:7 - line:2:32] decl=Foundation.(file).NSNumber.shortValue
                (call_expr type='NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:30] nothrow
                  (constructor_ref_call_expr type='(char: Int8) -> NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] nothrow
                    (declref_expr implicit type='NSNumber.Type -> (char: Int8) -> NSNumber' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] decl=Foundation.(file).NSNumber.init(char:) specialized=no)
                    (type_expr type='NSNumber.Type' location=example.swift:2:7 range=[example.swift:2:7 - line:2:7] typerepr='NSNumber'))
                  (tuple_expr type='(char: Int8)' location=example.swift:2:15 range=[example.swift:2:15 - line:2:30] names=char
                    (member_ref_expr type='Int8' location=example.swift:2:27 range=[example.swift:2:22 - line:2:27] decl=Swift.(file).Int8.min
                      (type_expr type='Int8.Type' location=example.swift:2:22 range=[example.swift:2:22 - line:2:22] typerepr='Int8')))))))))))

I want to point out that these are identical, as far as I can tell.  This makes sense because the behavior is set within the standard library.  This also implies that it is not possible to change the behavior while compiling user code.  As another exercise, you can tell clang to use signed or unsigned chars and there will be no change:

wdillon at tegra-ubuntu:~$ swiftc example.swift  -Xcc -funsigned-char
wdillon at tegra-ubuntu:~$ ./example
128
wdillon at tegra-ubuntu:~$ swiftc example.swift  -Xcc -fsigned-char
wdillon at tegra-ubuntu:~$ ./example
128

>>> What about a proposal where we would always map 'char' to Int8,
>>> regardless of the C's idea of signedness?
>>> 
>> 
>> In a very real sense this is exactly what is happening currently.
> 
> Sorry, I don't see that yet -- it is still unclear to me what is happening.
> 

That’s ok.  We’ll keep working on it until I’ve proven to everyone’s satisfaction that there really is a problem.

Cheers,
- Will




More information about the swift-evolution mailing list