Live data from Hacker News

Ask HN: A retrofitted C dialect?

news.ycombinator.com

31–40 of 81 posts

Re: Ask HN: A retrofitted C dialect?

#31
Here is a sound static analyzer that can identify all memory safety bugs in C/C++ code, among other kinds of bugs:

https://www.absint.com/astree/index.htm

You can use it to produce code that is semi-formally verified to be safe, with no need for extensions. It is used in the aviation and nuclear industries. Given that it is used only by industries where reliability is so important that money is no object, I never bothered to ask them how much it costs. Few people outside of those industries knows that it exists. It is a shame that the open source alternatives only support subsets of what it supports. The computing industry is largely focused on unsound approaches that are easier to do, but do not catch all issues.

If you want extensions, here is a version of C that relies on hardware features to detect pointer dereferences to the wrong places through capabilities:

https://github.com/CTSRD-CHERI/cheri-c-programming

It requires special CHERI hardware, although the hardware does exist.

Re: Ask HN: A retrofitted C dialect?

#32
I believe what programmers actually want is clean dialect-free C with sidecar files.

It seems people pretty universally dislike type annotations and overly verbose comments, like Ruby's YARD or Java's Javadoc. Also, if your new language doesn't compile with a standard C compiler, kernel usage is probably DOA. That means you want to keep the source code pure C and store additional data in an additional file. That additional file would then contain stuff like pointer type annotations, object lifecycle and lifetime hints, compile-time eval hints, and stuff to make the macros type safe. Ideally, your tool can then use the C code and the sidecar file together to prove that the C code is bug-free and that pointers are handled correctly. That would make your language as safe as Rust to use.

The hardcore C kernel folks can then just look at the C code and be happy. And you and your users use a special IDE to modify the C code and the sidecar file simultaneously, which unlocks all the additional language features. But as soon as you hit save, the editor converts its internal representation back into plain C code. That means, technically, the sidecar file and your IDE are a fancy way of transpiling from whatever you come up with to pure C.

Re: Ask HN: A retrofitted C dialect?

#34

In 2014 John Regehr and colleagues suggested what he called Friendly C[0], in an attempt to salvage C from UB. About bit more than a year later, he concluded that the project wasn't really feasible because people couldn't agree on the details of what Friendly C should be.[1] In the second post, there's an interesting comment towards the end: > Luckily there’s an easy away forward, which is to skip the step where we t…

> Luckily there’s an easy away forward, which is to skip the step where we try to get consensus.

This is true, the Benovolant Dictator model, versus the Rule by committee model problesm.

Committees are notorius for having problems coming to a consensus, because everyone wants to pull in a different direction, often at odds with everyone else.

Benevolent dictators get things done, but it's not necessarily what people want.

And, we live in hope that they stay benevolent.

Re: Ask HN: A retrofitted C dialect?

#36
post #18

> So unlike a few `unsafe` in a safe Rust, I want something like a few "safe" in an ambient "unsafe" C dialect. But I'm not saying "unsafe" is good or bad, I'm saying that "don't talk about unsafe vs safe", it's C itself, you wouldn't say anything is "safe" or "unsafe" in C. Eh? The critical criterion is "does your language make it difficult to write accidental RCEs". There's huge resistance to changing language at a…

[deleted]

Re: Ask HN: A retrofitted C dialect?

#37
You mentioned D, but are you familiar with D's BetterC?

https://dlang.org/spec/betterc.html

The goal with BetterC is to write D code that's part of a C program. There's no runtime, no garbage collector, or any of that. Of course you lose numerous D features, but that's kind of the point - get rid of the stuff that doesn't work as part of a C program.

Re: Ask HN: A retrofitted C dialect?

#38

I think you don't need any rants but here it goes anyway. Ditching headers does not solve anything at least if your language targets include performance or my beloved example Gamedev =) . You will have to consume headers until operating systems will not stop using them. It is a people problem not language problem. Big elephants in the room I do not see in your list: 1) "threading" was bolted onto languages like C and…

Exactly the kind of thoughts and insights I need from more of the users. Thank you for pointing out many concerns. > Headers. C++20 modules are left unstable and unused in major compilers there, but it’s a standard. And C is ironically perfect for FFI, as I said, almost every programming language speaks C: Rust WebAssembly API is extern C, JNI in Java, every scripting language, even Go itself talks to OS solely using…

> > Optimization, hardware.

> Quite don’t understand why these concerns are “concerns” here.

One of the most frustrating things about C is that it is generally taught together with assembly, so that there is a general conflation between C and assembly, as if C is both "just" some sort of portable assembler and the unique language with that property. The main consequence of this is that the C abstract machine [1] tends to be assumed to be the model of how processors work, and this ends up creating a lot of friction where the C abstract machines just doesn't match hardware newer than about 40 years old. It can be a little hard to understand just how bad the friction is if you haven't personally run across it, but here's a few examples:

* Registers. C doesn't have a concept of registers [2], and there's not much of an easy way to really distinguish between "things that look like a load/store because the abstract machine assumes everything has a memory location" and "no, this is meant to actually issue a hardware machine load/store or this is meant to actually permanently live in a register." There's also minor stuff like the fact that the language makes it easier to express "A[i]" (load A + i * sizeof(A)) over "&A[i]" (A + i sizeof(A)) that makes it somewhat annoying if you want to express assembly concepts better.

SIMD vectors. This is pretty common (at least across a desktop, server, or mobile CPU or GPU). But C has no way of expressing these types or how to use them, outside of compiler extensions (and there's like three incompatible versions of it).

* There's a lack of concept of optimization, and concomitant issues like optimization barriers. Some things have slowly moved in (e.g., there's now an attribute to indicate a function call is speculatable), but in general, it's still difficult to tell the compiler to stop doing some optimization that might break your code.

* No hardware speculation barrier concept, and similar other barriers for more exotic concepts like operations depending on the path condition of the function call (cryptographic code, which wants to be constant-time, or SIMT code tends to care about that a lot more).

[1] Or at least what people assume the semantics of the abstract machine are. Let's be frank, the C userbase isn't very good at actually knowing what the C standard does and doesn't guarantee.

[2] Yes, I know about the register keyword. No, it doesn't give C a meaningful concept of registers.

Re: Ask HN: A retrofitted C dialect?

#39
Here's a thing... There's been many of them and they all die because they don't provide enough benefit over the status quo. Cyclone https://en.wikipedia.org/wiki/Cyclone_(programming_language) is probably the most known one. There's Safe C https://www.safe-c.org/ A bit further from just "dialect" there's OOC https://ooc-lang.github.io/ and Vala https://vala.dev/

But the only thing that really took off was effort to change things at the very base level rather than patch issues: Rust, Zig, Go.

Re: Ask HN: A retrofitted C dialect?

#40
If the goal is something that can be used to improve existing C code, I have a few thoughts.

To get to memory safety with C:

- Add support for array bounds checking. Ideally with the compiler doing the heavy lifting and providing to itself that most runtime bounds checks are unnecessary.

- Implement trivial dependent types so the compiler can know about the array size field that is passed next to a pointer. AKA

void do_something(size_t size, entry_t ptr[size]);

- Enforce the restrict keyword. This is actually the tricky bit. I have some ideas for a language that is not C, but making it backwards compatible is beyond where I have gotten. My hint is separation logic.

- Allow types to change safely. So that free() can change the type of the pointer passed to it, to be a non-dereferencable pointer (whatever bits it has).

This is an idea from separation logic.

Allowing functions to change types of data safely could also be a safe solution to code that needs type punning today.

I think conceptually modules are great, but if your goal is source compatible changes that bring memory safety then something like modules is an unnecessary distraction.

Any changes that ultimately cannot be implemented in the default C compiler I don't think will be preferable to just rewriting the code in a more established language like Rust.

On the other hand I think we are in a local maxima with programming languages and type systems. With everyone busy recombining proven techniques in different ways instead of working on the hard problem of how to have assignment, threading, and memory safety. Plus how to do proofs of interesting program properties with things like asserts.

Unfortunately it appears that only through proof can programs be consistent enough that specific security concerns can be said to not be problems.

What I have seen of ADA Spark lately has been very tantalizing.

I have a personal project that I think I have solved the memory safety problem, while still allowing manual memory management and assignment. Unfortunately I am at a stage where everything is mostly clear in my head, but I haven't finished fleshing it out and proving the type system, so I really can't share it yet :-(.

While implementing modules, memory safety, type variables, and functions that can change the types of their argument pointers. I think I will end up with something simpler than C in most respects.

I keep going well that doesn't make any sense today, as I go through all of the details and ask why is something done the way it is done.

One of those questions is why doesn't C use modules.

Post reply on HN