Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C is only the OS ABI in operating systems written in C.


Which is all the ones that matter the most for this discussion due to market share / mindshare.


Good luck using the C ABI on ChromeOS or Android.


Android is Linux-based and has many of the same problems. Chrome OS too if you’re writing to the metal.


Good attempt.

Android userspace uses Java and can only talk to native code via JNI, which definitely isn't a C ABI.

Likewise there isn't any writing to metal on ChromeOS for the official userspace APIs, running Linux (Crostini) implies running a sandboxed version on top of the actual ChromeOS, while Android on ChromeOS not only has the same JNI restrictions, it also is sandboxed without access to host OS.

EDIT: I also forgot that ChromeOS and Android expose many of their key APIs to native code via OS IPC, on top of the constraints mentioned above. With endpoints written in a mix of C++, Java and now Rust.


JNI is very much a C ABI, yes. I should know, for I've written JNI FFIs more than once. Yes, you can also write JNIs in C++, but you don't have to because JNI's ABI is C not C++, and that is because C++ ABIs were not stable decades ago when JNI was written.


JNI isn't a C ABI from the point of view what is being discussed here, it is a marshaling library.

You don't do OS syscalls via JNI, rather marshal representation of Java objects for consuptiom from native languages.


You clearly haven't written a JNI.

JNI is an API between the JVM and C- or C++-coded plugins that can implement native methods. "Native method" means "written in C (or C++)". There's a) a standard interface that C-coded methods must present (depending on their Java signature) and b) a set of utility C functions provided by the JVM.

Because these plugins are loaded via `dlopen()`/`LoadLibrary_Ex()`/etc. the JNI API has an ABI.

If you don't believe me go look it up. There's a ton of resources on JNI. Here's an example taken from the wikipedia page on JNI:

  extern "C"
  JNIEXPORT void JNICALL Java_ClassName_MethodName
    (JNIEnv *env, jobject obj, jstring javaString)
  {
      const char *nativeString = env->GetStringUTFChars(javaString, 0);
  
      //Do something with the nativeString

      env->ReleaseStringUTFChars(javaString, nativeString);
  }


I would even go as far as to say that a good OS ABI only uses a safe subset of C. This excludes pass-by-value structs (and vector types), struct returns, and maybe even bitfields.

Even with these restrictions in place, modern register-based calling conventions can be still be rather complex, but these restrictions reduce it somewhat. They help to avoid areas in which implementations traditionally diverge, too.


What's wrong with pass-by-value structs? Yes, I'm aware that long ago there was a problem on SPARCs where Sun Studio and GCC handled struct value returns differently, but not pass-by-value. ABIs can and do define how to do pass by value of values of struct types.

The bits of C that need to be avoided in APIs are:

  - bitfields unless no bitfield crosses a
    byte boundary
  
  - struct fields of enum types (because the
    size of the enum type is implementation
    specific)
The spec should fix this, damnit.


Even if you go into niche OSes and find one not written in C, I doubt what you said will be correct.


You can start by learning about IBM and Unisys mainframes and microcomputers.

Then dive into Vax/VMS with Bliss, Multics with PL/I and plenty of others that lost to UNIX.


Oberon one could guess by seeing it's an OS and its implementation language, tightly coupled under the same name, that Oberon's ABI uses Oberon.

Loosely defined, most embedded Forth systems act as an OS and they tend to use the system's assembly or the Forth system itself as the ABI.

PC-DOS derivatives obviously use x86 registers and interrupts as an ABI - that's more assembly and machine language oriented than C.


C is the wrong tool for defining ABIs.


C isn't used for defining ABIs. ABI's have content in them like which registers must be saved by a called function and which ones carry arguments. None of that is C. However, out of necessity, ABI definitions refer to some C concepts and must include details like how structures are to be laid out by C compilers.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: