[swift-evolution] [Draft] Target-specific CChar
michel.fortin at michelf.ca
Fri Mar 4 19:52:41 CST 2016
> As it stands, Swift’s indifference to the signness of char 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 unsigned char; in this case the current import model certainly violates the Principle of Least Astonishment.
> This is not an abstract problem that I want to have solved “just because.” This issue has been a recurrent theme, and has come up several times during code review. I’ve included a sampling of these to provide some context to the discussion:
> • Swift PR–1103
> • Swift Foundation PR–265
> In these discussions we obviously struggle to adequately solve the issues at hand without introducing the changes proposed here. Indeed, this proposal was suggested in Swift Foundation PR–265 by Joe Groff
I don't want to downplay the issue, but I also wouldn't want the remedy to be worse than the problem it tries to solve.
One remedy is to have char map to Int8 or UInt8 depending on the platform, but this introduces C portability issues in Swift itself so it's not very good.
Another remedy is to have an "opaque" CChar type that you have to cast to Int8 or UInt8 manually. While this removes the portability issue, it introduces friction in Swift whenever you need to use a C API that uses char. It also introduces a risk that the manual conversion is done wrong.
Given the distribution of platforms using an unsigned char by default, I do wonder if there are libraries out there that actually depend on that. It seems to me that any C code depending on an unsigned char by default is already at risk of silently producing wrong results just by moving to a different CPU. In most circumstances, that'd be considered a bug in the C code.
So, my question is: are we contemplating complicating the language and introducing friction for everyone only for a theoretical interoperability problem that would never happen in practice? I would suggest that perhaps the best remedy for this would be to just translate char to Int8 all the time, including on those platforms-architecture combos where it goes against the default C behavior. Just document somewhere that it is so, perhaps offer a flag so you can reverse the importer's behavior in some circumstances, and be done with it.
More information about the swift-evolution