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

The author is not talking about C but about the C ABI that is the default OS ABI.

It's an ABI, there have to be one, and C was the de-facto system programming language.

I don't get the complaint, there are flaws, it could have been much MUCH worse.



The complaint is that C isn't the only systems language anymore so defining the ABI in terms of executable C code is a pain-in-the-ass for those other languages.

C is also a terrible language to define an ABI because, by design, it's very imprecise in the way that it defines types.


> it's very imprecise in the way that it defines types.

It's perfectly precise, particularly if you choose to use <stdint.h> which has been available in the language for a very long time. You may have some issues with specific types and platform variability, but it's absurd to cast this as "it's imprecise with types."

It's _flexible_ with types.

People seem to miss that this is the reason why C is the lingua franca. It isn't trying to "perfect" computing. It just makes it possible. There's a lesson for new languages here.


> The complaint is that C isn't the only systems language anymore

C was never the only systems language.


For a long time on UNIX it definitely was, until it got its sibling CFront in the package.


What kind of precision would you like to see added to the way C defines types?


It would be nice if you could just look at an interface and know it returns a 32-bit integer without parsing four C headers to get that information.


C's variables always scale to use the underlying hardware in the most efficient way in terms of performance. There's always sizeof() and macros to get the size of the variables you have.

This is why C is mostly portable with minimum effort unless you do hardware specific things, or use the variable to their limits. In that case you can always define fixed size types.

I don't get why people love to bash C. No language has an obligation to do please the programmer in its default modus operandi. Programming languages exist to interface hardware with humans, and C operates in the realm of the hardware, and that's perfectly OK for me.


No they don’t. If we cared about that we’d be using ILP64 instead of keeping int at 32 bits for compatibility reasons. I’m not here to bash C, anyhow; I think you’re failing to consider that I have experience with C and what it’s not good at, and am able to look past trite statements like “C interfaces with the hardware” that aren’t true or useful. In this case the concern is that C doesn’t make it convenient to talk to hardware!


That is the pitch, but not the reality.

C ABIs (of which there are many because the C standard doesn’t cover ABI) are full of legacy cruft, because they need to be stable and backwards-compatible more than they need to be sensible or efficient.

The C ABI can even vary depending on compiler flags, e.g. availability of AVX affects calling conventions. It’s not easy to be interoperable with this, especially when ABI-affecting compiler flags and macros may be set by an arbitrary build system, not even the C source code.


I think if it was any worse, it (Linux, BSD, etc) wouldn’t function at all. So it is maximally worse for the subset of things that function. It’s like getting all the worst medical conditions that don’t actually kill you. Sure, there are worse diseases: you could be dead. Is that any comfort? Probably not. Probably be looking for a cure.


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.


There isn’t the C ABI, as the article actually mentions. There are various ABIs, most of which (but not necessarily all) can be targeted by a combination of C declarations and compiler switches.

The one thing that could be improved is to come up with a better language than C headers to specify cross-language APIs/ABIs.

The fact that different ABIs exist cannot be helped. That’s something one has to cope with in any case, independently of C.

One way to sidestep many of the issues is to target the JVM. ;)


agreed, much of the bickering is on ABIs and FFI stuff which you could argue is hard due to ABI differences it supports. this is not a C problem, but a complexity C exposes. C does do that a lot, but thats also a strength. There are really no sound alternatives to C for low level system programming (OS core functionality, or embedded stuff). there's C++ ofcourse but regarding the complaints it suffers the same. Rust doesnt solve anything there, its impossible still to actually build a modern OS in rust for example. (maybe if most your core is wrapped in unsafe and you run on only a single core device...).

If C is such a problem id like to see some alternatives which offer what C does but less painfully.

C is only useful in certain domains, but within the domains where C is really good, theres no others. (unless you want to go assembly mode... good luck :) can be fun)..

anyhting that is less painful, exposes less complexity and is usually therefore less generally applicable.

A lot of the pains of C are lack of understanding how to use it because using it requires deep knowledge of it, and the target platform.

that being said, i do get userland applications and C dont really mix anymore. that is a fair point imho.


It could be worse, but for the long-term evolution of computing, we should be working towards convergent systems. There's enough subtlety and imprecision in the C spec that it's not well suited to convergence.

Among type issues, it also has the infamous "Macros" that are really just unanalyzable text replacements.


> I don't get the complaint, there are flaws, it could have been much MUCH worse.

I find it amusing that after half a century of existence and powering the world's IT infrastructure, suddenly some illuminated individual felt entitled to claim they alone found problems that they alone can fix.




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

Search: