He might mean that char
is unsigned. char
in C is always a distinct type from either signed char
or unsigned char
, and whether char
itself is signed or not is implementation-defined.
Yeah but he's wrong. I checked. By default, char
is signed on Windows. There is an MSVC++ flag you can pass to make it unsigned, however.
It is what @Joe_Groff was saying - I was thinking about char
. I might have had it backwards though - Windows has a signed char
and Darwin has unsigned char
perhaps?
⌠char
is signed on Windows and on Darwin.
I would phrase it as compiler-specific, not platform-specific. char
is signed by default by Visual C++âs CL.EXE unless you pass /J
, which the docs warn may cause ATL or MFC apps to fail to build. I did a quick search but couldnât find anything about whether the Windows SDK itself has a dependency on char
being signed.
Indeed, MSVC++ likes having options for everything.
Does clang have an equivalent to /J
? If not, it seems moot, since Swift's C interop is ultimately based on the view of C exposed by clang.
GCC has -fsigned-char
, which clang inherited. When invoked as clang-cl
, clang also supports /J
.
Since Swift does not invoke clang-cl, sounds like it is indeed moot.
Please reread :)
-fsigned-char
is the default for Windows, you can use -funsigned-char
to mimic /J
.
Since Swift does not pass -funsigned-char on its own, it's still moot.
My original pointâthat none of the major vendors use unsigned char
by default, and so the unknown signedness of CChar
makes a portable C module more difficult when we could maybe just put our foots down and say "it's always signed in Swift"âstill stands.
Oh yes, good point, there are a bunch that need to be macros/inline functions for performance too.
Yes, that makes sense. This might even be an opportunity to also deal with errno
. Currently, there's no guaranteed way to deal with errno
correctly in Swift because any libc (or others that write into errno
) function call may overwrite the value. But we have ARC which deterministically but mostly unpredictably (particularly under inlining) places swift_release
calls, which might turn into deinit
s which runs arbitrary code. Hence, we may want to fetch the return value & errno
together without running any Swift code in between.
Thatâs how system calls actually work, at least on Linux. errno is just a fiction created by libc. So maybe we could bypass libc entirely and just wrap the system calls directly like Go does.
Unfortunately, this really only works on Linux. No one else has stable syscalls, especially not Darwin.
There are also standard C and POSIX calls that set errno but aren't backed by syscalls. So we would still need a way to call one of those functions and grab the subsequent errno as a single operation to interact with those APIs.
For instance, if
_GNU_SOURCE
isn't defined before you include a header from glibc, you don't get access to all its interfaces. And SwiftGlibc.h (?) doesn't define_GNU_SOURCE
, so in order to access something likepthread_setname_np()
, you need to either resort to dynamic loading withdlsym()
or to adding a C module to your package that provides wrapper functions. (Swift Testing has both. Yay.)
Speaking of _GNU_SOURCE stuff, it reminds of the discussion of using dladdr in Swift. Many people (including me) has a demand for it and currently we have to use a C shim layer to export it for Linux platform.
I recall having a real problem importing liburing because its header defined _XOPEN_SOURCE, which makes all the socket structures incompatible. The workaround was not elegant.
Cross posting as I meant to add it to here
That seems like a left-pad fix, which may work for SwiftPM packages but not for alternative build systems like CMake and Bazel or within the toolchain itself (note how many files he had to add that new FreeBSD overlay to in just the compiler repo).
I'm not against trying your idea out, but it has to be vended by someplace official, given the obvious scope for abuse, say from @0xTim and the swift-server org? If they agree, I'm happy to pitch in to create this simple import alias there.
I don't expect to ever "fix" it, the idea would be to replace it altogether with your import C99
idea or whatever the community comes up with then. The Swift team has pragmatically added such temporary features like @_cdecl
to the compiler in the past, to provide some incomplete solution for today while we figure out a better solution to finally add to the language later.
I see no reason we can't put this alias in now as import _platformC
or whatever ridiculous name to signify it is temporary, write some doc to emphasize how limited it is, and ship it in the stdlib today to fix a small but real problem for those writing multi-platform code.
I was going to say that there's nothing that would stop the compiler project from adopting an internal shorthand for itself (much as it's already done for availability attribute), but I see that many of these uses are non-trivially different from each other, including some that declare typealiases, so it's not clear to me actually how much mileage such an internal feature would get. It's also not clear to me how many are using only C standard library facilities versus platform APIsânot that it clinches the point, but I see a lot of import Darwin
and no import Darwin.C
.
I wonder what that breakdown would be for third-party uses of the import dance today--if people tend to customize the platforms recited and want the entire platform SDK for each, then the ask isn't some precursor that can ever be replaced with import C99
.