Live data from Hacker News

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

cl.cam.ac.uk

161–170 of 253 posts

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

#161

Earlier quoted context omitted.

shrug It doesn't fall over. I've done it, the openBSD team has done it. DJB has done it. Maybe something is wrong with your implementation that I can help you with?

I'm curious. Got links?

OpenBSD takes a fairly minimalist approach, which is vaguely described here: http://www.freebsdforums.org/forums/showthread.php?threadid=... They basically replace the unsafe functions with things that are easier to use. Their idea is that it isn't the format of the C-string that causes security issues (null-terminated string), it's the poorly defined functions (with weird corner cases that are hard to get right). It's worked well for their use cases.

DJB did something similar in qmail, I don't recall the details but you can look at the source code as easily as I can, and it eliminated security problems.

When I'm working in Java, I find that most of my string parsing uses the split() function. This is a pain in C, because even if you had a split() function you'd need to deal with memory allocations. Most of these are solved with a memory pool. In my own library, I also added runtime, grammar-based parsing functionality. So to parse a CSV line you might do something like this:

    char *g = " S   -> WORD | WORD , S;"
              "WORD -> [^,]";
    results = parsegram(g, inputString);
Grammar parsing + memory pools makes string parsing in C easier than in Java. The biggest difficulty with this kind of library is to do it right, you need to be something of a unicode expert, and that's tough.

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

#162

Earlier quoted context omitted.

To create an external index for the existing collection, I need to get pointer of the item stored in that existing collection, compute a key, and put both into the HashMap So, I need to do both. And also, I need to know when these pointer expire so I can rebuild my index when it happens.

I think I understand. The idea would be to have one HashMap that holds the objects themselves, and then a secondary HashMap (with a star this time) that indexes on some other key and points to values stored directly in the first map? What's the benefit of doing that, compared to making both the HashMaps store pointers to independently allocated objects on the heap, such that insertions into one map never invalidate t…

> Is the hope to avoid paying the cost of an extra pointer dereference when we're using the first map? Or does independently allocating each object hurt cache locality or something like that?

Both.

In practice, I probably wouldn’t use a hashmap for the first container that actually owns these items. When I do expect gigabytes of data, in C++ I use something like vector>, where the inner vectors are of the same fixed size (except for the last one), e.g. 2-16MB RAM / each. If I need to erase elements, I include a free list such as this one: https://github.com/Const-me/CollectionMicrobench/blob/master...

But the exact container is not that important here. If you don’t have that many values, it can as well be a standard vector.

The point is, C++ allows composing these containers making higher-level ones, such as this indexed array example, using pointers to link individual items across them. This feature allows building sophisticated and efficient data structures that are still possible to reason about.

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

#163

Earlier quoted context omitted.

To create an external index for the existing collection, I need to get pointer of the item stored in that existing collection, compute a key, and put both into the HashMap So, I need to do both. And also, I need to know when these pointer expire so I can rebuild my index when it happens.

I think I understand. The idea would be to have one HashMap that holds the objects themselves, and then a secondary HashMap (with a star this time) that indexes on some other key and points to values stored directly in the first map? What's the benefit of doing that, compared to making both the HashMaps store pointers to independently allocated objects on the heap, such that insertions into one map never invalidate t…

Object size possibly.

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

#164
post #7

This is another article overanalyzing the success of C, when in fact the reason for the success of C is very simple and obvious: Unix was free and in a lucky position in 1973; Unix got popular; C is the language of Unix; therefore C got popular. There is no inherent benefit in C that, for example, a somewhat modified version of Pascal or Algol wouldn't have inherited. And these kinds of articles always ignore the fac…

A "somewhat modified version of Pascal or Algol" would be just C with a different syntax.

C is remarkable for what it doesn't have. It sits at a nice local optimum point that a portable assembler must occupy.

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

#165
This paper would be readable outside usual programming.

In fact, I wonder what other may feel to read the page just before Section 4. It is funny. Also as C is used in everywhere, it is not that funny.

But the first quote in first page is quite a good starting point to understand Brexit and Trump's crowd. Take the recent action to "deal with" the 800,000 kids, it is the problem of the Obama that want to extend them to their parents that now hurt the child. If we keep some dangerous element, some germs, not pure, not totally PC, may be the world is a better place.

As that Taoism would argue - the Big Thief would not be dead until the Great Saint is all dead. We are human not God. And we need C. Those academic common consensus to pursue ideal and nirvana create bad language. We need to keep C and find its proper role. Like keeping the world in a pure Buddhist world - not to save it, not to say it is a 2nd grade world cf nirvana but as it is.

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

#166
post #22

Earlier quoted context omitted.

> Switching to a new compiler is a very high burden for a lot of projects ... By contrast, switching to a new language ... is also a very high burden, but the benefits are larger I guess switching to a new compiler (or newer version of the same vendor) is much less burden than switching to the new language. Don't forget that all "new safe languages" are simply new. Why people like C is familiarity: known practices an…

> I guess switching to a new compiler (or newer version of the same vendor) is much less burden than switching to the new language. If that were true, then Linux distros wouldn't still be using GCC. Switching to a new compiler (like clang) is a huge burden. Both switching compilers and switching languages are enormously expensive, to be sure. But I think people (especially people in academia) consistently underestima…

> If that were true, then Linux distros wouldn't still be using GCC.

You're presupposing they want to switch. Most of the switchers to clang seem to have done so for ideological reasons more than anything.

Never the less, most of debian can be built with clang: http://clang.debian.net/

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

#167
post #103

Earlier quoted context omitted.

> There's a third kind, which uses indexes into arrays containing the nodes and edges Pointers are still faster. Also with arrays it’s expensive to reduce RAM usage after a lot of nodes were removed. > Can any of these protect against the scenario where a block of memory is freed, allocated again for another purpose, but still accessed through the old dangling pointer? No 100% guarantee, but AFAIR CRT debug heap take…

> Pointers are still faster. Depending on cache effects, indexes might or might not be faster than pointers. With indexes into an array, the nodes or edges will be sequential in memory, which depending on their size and access patterns might increase the cache hit rate. Furthermore, while pointers will always be 8 or 4 bytes, indexes can be as small as 2 or even 1 byte for smaller graphs (reducing structure sizes and…

Your point about reducing pointer size if the size of allocation pool is smaller makes sense. But I think it is not fair or realistic to imply that simply using an array the size of all RAM starting at zero leads to more fragmentation than referencing all of RAM relative to some other point. Assuming same algorithms working on same sized data sets. The relative locations of objects is not dependent on where the coordinate origin is, although choosing a good zero may make the engineer's life easier.

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

#168

Earlier quoted context omitted.

I'm curious. Got links?

OpenBSD takes a fairly minimalist approach, which is vaguely described here: http://www.freebsdforums.org/forums/showthread.php?threadid=... They basically replace the unsafe functions with things that are easier to use. Their idea is that it isn't the format of the C-string that causes security issues (null-terminated string), it's the poorly defined functions (with weird corner cases that are hard to get right). It…

I used snprintf(), too, but it is only a minor improvement. Problematic in C is something as simple as concatenating strings:

    Mystring s,t;
    t = "hello";
    t = cat(s,s);
    t = cat(s,s,s);
    t = cat("hello",s);
    t = cat(s,"world");
    t = cat("hello","world");
Even such a simple use case is fraught with major problems:

1. who allocates needed memory?

2. who free's it?

3. can the compiler constant fold cat("hello","world") ? Does the result wind up allocating memory anyway?

4. what about the lack of function overloading to handle the permutations?

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

#169

Earlier quoted context omitted.

Have you considered C#? It only has a single string class. With async-await, concurrency is fine too. Not long ago, they open sourced the compiler and a subset of runtime, making it cross-platform: https://github.com/dotnet/core It’s a but tricky to install on Linux, but for me it works OK, at least so far (an embedded TCP/UDP server app).

I haven't, and its a good idea. I wrote a bunch of C# code back in 2007 and I consistently enjoyed it. - It seems like a very pragmatic language choice. But if I'm going to move further away from the hardware in exchange for some language comforts & quality of life improvements, Elixir is the next language I want to try. I think both its concurrency primitives and immutability rules might be the right language-level…

> move further away from the hardware in exchange for some language comforts & quality of life improvements

C# has descent native interop, i.e. [DllImport]. On Linux it imports from .so dynamic libraries. When you want to be closer to the hardware, because SIMD, or system calls not exposed to .NET, or integration with third-party C code, it usually works OK.

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

#170
post #113
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…

C's popularity is due to the fact that it is predictable within certain bounds (single thread or limited concurrency). No GC pauses, no weird runtime crashes due to a strange constructor, no gigantic exception chains, etc. The only languages in the TIOBE index that can even try to make that claim are: C at #2, C++(if you subset it) at #3, Objective-C/Swift(#18/#11), Assembly at #14, Ada at #29, and maybe FORTRAN(#35)…

Once upon a time it was common to write non-consing Lisp code precisely in order to get predictable behaviour; I think that it worked pretty well. Non-consing code won't have GC pauses; it won't have weird runtime crashes; and it probably wouldn't have gigantic exception chains unless it needs them.
Post reply on HN