I understand.
First, I meant a uniform compile time ABI. Not an ability to mix and match at runtime. That is much less to ask for than discussed after me. I simply want to compile two .objs with the different compilers and headers, and then link them together, trafficing in whatever. The ABIs are already largely the same, just because there's a lot of function calls and opaque ints and opaque void*. It is the structs and #defines where things can vary. (or any use of __inline in a header, not a standard C construct, but it happens) Sometimes usefully, like the example of stat returning more information, sometimes not so usefully, like if the errno values are different. As well, you (sorry, no attribution) exaggerate the reality. These things can definitely mix, in certain very careful ways. Otherwise Cygwin wouldn't even be able to run on the system. Or any other C/Posixy runtime library. But this is indirect, indirect dynamic linkage. There is a C library to some extent below in kernel32.dll, ntdll.dll, ntoskrnl.exe. Look at ntdll.dll and ntoskrnl.exe exports. Lots of stuff missing though. Like fopen, and stat. \bin\x86\cdb.exe \cygwin\bin\sh ModLoad: 00400000 0047a000 image00400000 ModLoad: 7d4c0000 7d5f0000 NOT_AN_IMAGE ModLoad: 7d600000 7d6f0000 D:\WINDOWS\SysWOW64\ntdll32.dll ModLoad: 7d4c0000 7d5f0000 D:\WINDOWS\syswow64\kernel32.dll ModLoad: 61000000 61200000 D:\cygwin\bin\cygwin1.dll ModLoad: 00580000 0061b000 D:\WINDOWS\syswow64\ADVAPI32.DLL ModLoad: 7da20000 7db00000 D:\WINDOWS\syswow64\RPCRT4.dll ModLoad: 7d8d0000 7d920000 D:\WINDOWS\syswow64\Secur32.dll ModLoad: 6f5c0000 6f5cd000 D:\cygwin\bin\cygintl-8.dll ModLoad: 674c0000 675b9000 D:\cygwin\bin\cygiconv-2.dll ModLoad: 703c0000 703ed000 D:\cygwin\bin\cygreadline6.dll ModLoad: 6c180000 6c1c0000 D:\cygwin\bin\cygncurses-8.dll ModLoad: 7d930000 7da00000 D:\WINDOWS\syswow64\USER32.dll ModLoad: 7d800000 7d890000 D:\WINDOWS\syswow64\GDI32.dll ModLoad: 71c00000 71c17000 D:\WINDOWS\SysWOW64\ws2_32.dll ModLoad: 77ba0000 77bfa000 D:\WINDOWS\syswow64\msvcrt.dll *** ModLoad: 71bf0000 71bf8000 D:\WINDOWS\SysWOW64\WS2HELP.dll ModLoad: 7db30000 7dbb0000 D:\WINDOWS\SysWOW64\mswsock.dll ModLoad: 77670000 777a9000 D:\WINDOWS\syswow64\ole32.dll ModLoad: 76ed0000 76efa000 D:\WINDOWS\SysWOW64\DNSAPI.dll ModLoad: 76f70000 76f77000 D:\WINDOWS\SysWOW64\winrnr.dll ModLoad: 76f10000 76f3e000 D:\WINDOWS\syswow64\WLDAP32.dll If I call msvcrt!malloc and pass that buffer as a struct stat to cygwin1!stat, no problem. It becomes difficult to navigate these areas just with #include and regular function calls, but once you start LoadLibrary / GetProcAddress, much more flexibility opens up. It is dangerous ground and your exaggeration is useful to most folks, since the reality is both complicated and rarely useful. I realize that the Microsoft ABI is frozen. And perhaps the Cygwin one is too. A thin static layer could in many cases bridge the gap, but not necessarily always or reliably. That is, let's say stat was reorganized, but the same fields were present. Then a thin layer would do. Look at how Linux implements stat for a similar but different example. I believe in their case, the kernel implements multiple interfaces. So the static layer doesn't have to move data around, but merely call ahead to the correct function. If errno.h varies -- there is no where to insert a function to alter things, and so no unification is possible, without breaking existing interface. I'd have to see if the errno.h values do vary. Microsoft omits: #define ENOTBLK 15 #define ETXTBSY 26 #define ENOMSG 35 #define ECHRNG 37 Microsoft: #define ENAMETOOLONG 38 #define ENOLCK 39 #define ENOSYS 40 #define ENOTEMPTY 41 #define EILSEQ 42 Cygwin: #define EL2NSYNC 38 #define EL3HLT 39 #define EL3RST 40 #define ELNRNG 41 #define EUNATCH 42 #define ENOLCK 46 #define ENOSYS 88 #define ENOTEMPTY 90 #define ENAMETOOLONG 91 #define EILSEQ 138 so unless the meanings actually "swap around", unlikely, it looks like ABI unification would be difficult, without forcing a break and recompile. It would have been possible, but now would cause pain. >> stat > (And, if we tried to align with > MS's definition, which one? vc6.0? vc7.0/2003, vc7.1/2003sp1? vc8.0/2005?) Have they really varied? If so, ouch. > keep FILE* opaque? >> And how is your code supposed to know when it is calling the different As long as FILE* is opaque, I could compile with one compiler and call fclose, pass that off to another source file, compiled with another compiler/headers, and call fopen. Consider the completely opaque int file descriptor on Unix, or HANDLE from CreateFile. People mix and match these with different compilers all the time. That's at the dynamic link level though. > ABI multiplicity bugs me.. Cygwin didn't necessarily have to add yet another one. But yeah there were already too many. Somewhere somehow these different worlds do come together. The question is where and how. There are several options. One common way for worlds to collide is only via the network -- TCP/IP, SMB. Another way is multiboot, sharing disks that way. Another way is removable media. Another way is via files on the same running system. Another way is via local or remote RPC (which again can include TCP/IP). Another way is via in-process function calls. This last one is where the bindings are tighter, the interfaces change more often, where "type checking" happens less. You know, IPv4 and IPv6 can identify each other and agree not to talk to each other, for example. But I don't pass a size (or version, or "layout description" of some sort) to stat for it to check. It trusts that we agree. Anyway, given the errno.h mismatches, it's not possible without a breaking change. Perhaps this can be "fixed" for any non-x86 Cygwin port? I realize, it requires visiting several factors and it ultimately might not fly. But mismatched errno.h doesn't seem like a good reason. - Jay -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/