Live data from Hacker News

Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

cl.cam.ac.uk

121–130 of 253 posts

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#121
post #32

Earlier quoted context omitted.

I've used both C and Pascal in embedded systems. Pascal is painful compared to C. A "somewhat modified" version might help, but I doubt it would be enough. To steal a phrase from my friend Michael Pavlinch: Pascal was like picking your nose with boxing gloves on. A modified boxing glove isn't really going to solve the problem. For that matter, once we weren't on Unix but rather on the PC, and we had a nicely-modified…

Basically because Microsoft picked C++ to be the main language for Windows development. Turbo Pascal was all very well but from Microsoft's point of view it was Not Invented Here.

C++ wasn't invented at Microsoft, either. The DOS C++ train had already left the station (Zortech C++) and Microsoft wasn't about to be left behind.

(Zortech didn't invent C++, either, I don't want to give that impression.)

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#122

Earlier quoted context omitted.

Excellent, I think the author would do well to re-frame the question as you have. If nothing else to put it more clearly into the space of provable compilation. When I transferred into the "Oak" group that later became the "Java" organization, the team I was on was looking at whether or not you could write an OS in Java sort of in spite of its safety rules. This sort of concept has been revisited by Rust with its saf…

The idea you can have a safe c compiler or runtime seems totally absurd to me. Why is any of this even considered seriously?

Indeed. Even the "obvious" example of the compiler inserting bound checks in the generated code does not work with the well-known method of marking the beginning of a variable-length memory block at the end of a struct using an array of some fixed size, say, 1 (or even 0).

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#123

Earlier quoted context omitted.

More like 20 it seems ;) > I need these two lower-level structures to expose unsafe stuff at the API boundary Two thoughts: 1) I think you can always use unsafe to get access to a raw pointer (I honestly don't use unsafe often) 2) you need someway to express ownership between both data structures, this can be annoying, no doubt. > C++, with these iterators and smart pointers Does that make it safer than unsafe Rust?…

> I think you can always use unsafe to get access to a raw pointer I’m not sure about that. Also I don’t know for how long will it work, C++ has iterator invalidation rules. > you need someway to express ownership between both data structures Not every relation is ownership. Graph modes don’t own each other, an external index doesn’t own the indexed items, etc.

I'm really not sure, but I think there's a miscommunication about raw pointers in this thread. I think other folks are suggesting that you can solve the container composition problems you're talking about by inserting raw pointers into a HashMap. But I think you're reading that as obtaining raw pointers to the storage that a HashMap owns, which is why you're worried about iterator invalidation rules and stuff like that? (My understanding is that any reference into storage that a container owns is / could be completely invalidated by any &mut operation on that container.)

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#124

Earlier quoted context omitted.

The idea you can have a safe c compiler or runtime seems totally absurd to me. Why is any of this even considered seriously?

Indeed. Even the "obvious" example of the compiler inserting bound checks in the generated code does not work with the well-known method of marking the beginning of a variable-length memory block at the end of a struct using an array of some fixed size, say, 1 (or even 0).

For that situation, you would need to mark the end of the variable-length memory block at run-time.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#125
post #5

This is a long paper and the author has 2 main claims: 1) C Language popularity is more to do with cognitive ease of memory addresses as a conceptual model for inspection and change. Author claims memory address mental model overshadows runtime performance . 2) switching to "safe" languages like Java/C#/Rust is not necessary. With no changes/violations to existing C Language specification, a new/different implementat…

> mental ease I'm a long time C programmer, and I was struck by how clumsy and error-prone any manipulation of C strings turns into. It's really hard to look at a mass of strlen/strcpy/memcpy/etc. and see just what is happening. Contrast that with, say, BASIC or Javascript, where string manipulation is easy, natural, and bug-free. I'm going to disagree about the mental ease of programming in C, and a large part of th…

That particular problem (strlen/strcpy/memcpy) comes from the problems of the standard library string functions. It can be solved by creating your own string library. Then string manipulation is easy.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#126

Earlier quoted context omitted.

I've been out of the C world for a long, long time but it seems to me that anywhere that C's pointer arithmetic and ability to cast pointers to/from other types is objectively appealing, that's going to be one of the cases that a compiler can't understand. Of course there's always the subjective "everything looks like a nail" usage as well, which makes every problem seem like a pointer problem because you've never tr…

In my case, nearly 100% of the C code I write is for embedded systems. Casting a hex literal to a pointer type that is a volatile hardware register is better than dropping into asm.... So yes, compilers will always have a hard time understanding device drivers and such unless you turn hardware device concepts into language primitives.

A more correct thing would probably be to create linker scripts that expose symbols for the registers. It's probably not worth the trouble now but the hypothetical compiler would understand it better.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#127
post #120

Earlier quoted context omitted.

There is no inherent benefit in C that, for example, a somewhat modified version of Pascal or Algol wouldn't have inherited. I happen to like C and think it has a lot going for it, but you're definitely right about this. The original Mac OS was written in Pascal (and assembly), not C. And Turbo Pascal was deservedly popular for a good while. In an alternate universe, Pascal rather than C could be the incumbent legacy…

You have to wonder, though, why the enduring big dogs of OSs are written in C. Classic Mac OS was written in Pascal, but it had to be scrapped and replaced.

I remember using System 7, which I later learned was the result of a big rewrite of much of the OS in C++ rather than Pascal. It had some nice features, and the rewrite was probably a wise decision for maintainability and future expansion, but compared to System 6 it was sloooooooooow

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#128
post #38

Earlier quoted context omitted.

C is frequently praised (including in some of the posts here) for its suitability for real-time and embedded systems development, but the author appears to be proposing modifying the C runtime and code generation in ways that, when done in other languages, are claimed to render them unsuitable for these purposes. I think researchers are justified in looking for solutions for common problems, even if many C programmer…

> C is frequently praised (including in some of the posts here) for its suitability for real-time and embedded systems development, but the author appears to be proposing modifying the C runtime and code generation in ways that, when done in other languages, are claimed to render them unsuitable for these purposes. Don't people think there are things C could improve that wouldn't affect its suitability for these task…

Tagged unions? -- please no... I could be convinced to completely lose unions in C, though (pointer to member or base of struct can be cast to another struct anyway, so losing unions doesn't gain anything; for the same reason tagged unions just would not be useful)

Boolean type? Sure, but that would be dependent on use. What is wrong with a bitfield one bit wide instead? What may be useful is "packed bitfield" type ("packed" in Pascal). Then, array of packed bit could be expressed.

Multiple return types - yes, "return a b;" (or something would be nice.

Lack of polymorphism - reference "void *" The main problem is that calls cannot be constructed in C (that is, the standard does not have a "C to C" FFI.

Anyway, just food for thought.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#129

Earlier quoted context omitted.

Use an Rc? If you can't afford the reference count, then use unsafe/raw pointers, which it sounds like you'd do in C++ anyway.

> then use unsafe/raw pointers Even if I manage to extract an unsafe pointer from that Rust collection, I don’t know for how long will it work. For C++ collections, iterator invalidation rules tell me that.

> Even if I manage to extract an unsafe pointer from that Rust collection,

It's easy, just get the & or &mut to the value (as if you were acessing it), and cast it to respectively * const or * mut.

> I don’t know for how long will it work. For C++ collections, iterator invalidation rules tell me that.

It's the same in Rust. Whenever the iterator would be invalidated in C++, the pointer you stashed above might point to the wrong place. This is not usually documented in Rust, because its borrow rules prevent you from stashing a reference while the collection mutates, but once you start playing with raw pointers, the borrow checker gets out of the way (references have a lifetime, pointers don't).

You just have to be careful when casting the pointer back to a mutable ref ("unsafe { &mut *ptr }" is the trick, see the documentation for std::mem::transmute): mutable references are like C99's "restrict", so you should make sure to only ever have one live for each pointer at every moment, otherwise you're in undefined behavior land.

----

Anyway, going back to the parent comment, you said "Values are not small, can’t afford duplicating them". Might I suggest keeping the values in a Box then, and making both collections point to the box? That way, you don't have to worry about a mutation in one of the collections invalidating the pointer, since the contents of a Box won't move in memory.

And in fact, the usual Rust style for keeping a value in more than one collection would be to use a Rc, which is basically a Box with a reference counter. That way, you don't need to play with raw pointers, and have no risk of a misstep. You pay the cost of incrementing/decrementing the reference counter only when adding/removing from the collection, and the reference counter is small.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#130

Earlier quoted context omitted.

> mental ease I'm a long time C programmer, and I was struck by how clumsy and error-prone any manipulation of C strings turns into. It's really hard to look at a mass of strlen/strcpy/memcpy/etc. and see just what is happening. Contrast that with, say, BASIC or Javascript, where string manipulation is easy, natural, and bug-free. I'm going to disagree about the mental ease of programming in C, and a large part of th…

That particular problem (strlen/strcpy/memcpy) comes from the problems of the standard library string functions. It can be solved by creating your own string library. Then string manipulation is easy.

That falls over as soon as you integrate with anybody else's C code, including the operating system APIs, and with C string literals :-(

If it was as easy as you say, it would have happened.

And heaven knows I wrote my own string packages, one after the other, and so did everyone else. I eventually abandoned all of them. C's abstraction abilities are simply not good enough to do a decent string encapsulation.

Post reply on HN