Live data from Hacker News

The Unreasonable Effectiveness of C

damienkatz.net

181–190 of 394 posts

Re: The Unreasonable Effectiveness of C

#181

Earlier quoted context omitted.

> Madhadron, you make a lot of claims but provide no detail. Also using terms like "virtual machine" with respect to C is plainly ridiculous and a case of bullshit baffles brains. C as a very thin virtual machine is a common conception and not an incorrect one--C runs on many systems with noncontiguous memory segments but presents it as a single contiguous space, for example. The idea of C as a virtual machine is muc…

> C as a very thin virtual machine is a common conception and not an incorrect one I have worked extensively in the past with C and have never heard it referred to as a virtual machine, thin or otherwise. I understand that the OP probably means "computation model" or something similar but felt that the use of the phrase "virtual machine" was a bit on the bombastic side and that in addition to the general tone of the…

"I have worked extensively in the past with C and have never heard it referred to as a virtual machine, thin or otherwise."

True. Usually other terms are used; for instance, "memory model". If you google that you'll find some things. As you read them, notice that they may or may not match the hardware you are actually running on, and given the simplicity of C's model, nowadays almost never does.

C is a low-level language that lets you close to the machine, and even lets you drop into assembler, but it is true that it is enforcing/providing a certain set of constraints on how the library and code will act that do not necessarily match the underlying machine. It may not be a "virtual machine", depending on exactly how you define that term, but the idea isn't that far off.

Also, this is a good thing, not a criticism. If it really was just a "high level assembler" that provided no guarantees about the system, it would be as portable as assembler, which is to say, not at all.

For a much more clear example of this sort of thing in a language similarly thought to be "close to the metal", look at C++'s much more thorough specification of its memory and concurrency model, and again notice that this model is expected to be provided everywhere you can use a C++ compiler, regardless of the underlying hardware or OS. It is, in its own way, a virtual machine specification.

Re: The Unreasonable Effectiveness of C

#182
post #50

Earlier quoted context omitted.

That's kind of the point. Why do you have to choose? Why isn't it possible with the language and its standard libraries? What happens when you mix APR code with glib-using code?

1. Because there is no standard defining that. 2. Because there is no standard defining that. 3. Nothing. Functions in both libraries are prefixed to avoid name clashes.

The lack of standard for 1+2 is the complaint here. Prefixing in the libraries is a workaround to make it possible at all for their separate (but similar) basic types to co-exist, but the libraries shouldn't have to define sane basic types for these things. At most they should have to add extended operations.

But because they don't, it must be reimplemented in each library that needs them, which adds to code size and semantic overhead. Which might be helpful is for a good basic type library to be created which could be a common dependency for each (perhaps host it on CCAN), but the fact that this would be needed at all is the base complaint.

Re: The Unreasonable Effectiveness of C

#183

Earlier quoted context omitted.

The Burroughs was a stack machine, but that's only the beginning. Look at how it handled addressing hunks of memory. Bounds checked memory block references were a hardware type, and they were the only way to get a reference to a block of memory. So basically, null pointers didn't exist at the hardware level, nor out of bounds writes to arrays or strings. Similarly, code and data were distinguished in memory (by high…

As a C programmer this is like watching virgins attempt to have sex. Normal people just write some code which does some sh*t and that's OK. We don't need to deeply reflect on whether it's cache optimal, because that will change next week. Just good clean C. When did that become a strange thing to do?

"good clean C"

Is there such a thing? It seems like every C program, even ones that are praised as being excellently written, are a mess of pointers, memory management, conditional statements that check for errors, special return value codes, and so forth.

To put it another way, look at the difference between an implementation of a Red/Black Tree in C and one written in Lisp or Haskell. Not only are basic things overly difficult to get right in C, but C does not become any easier as problem sizes scale up; it lacks expressiveness and forces programmers to deal with low-level details regardless of how high-level their program is.

Re: The Unreasonable Effectiveness of C

#184
post #103

Earlier quoted context omitted.

It may be the parent comment is referring to the Runtime-Library when using the term Virtual Machine.

No, I am referring to the virtual machine defined by the C language.

I'd say "abstract virtual machine." You are just confusing people. "Virtual machine" most commonly refers to a discrete program that presents a defined computational interface that everyone calls the virtual machine. This VM program must be run independently of the code you wrote.

For C there is no such virtual machine process. The "virtual machine" for C is abstract and defined implicitly.

Re: The Unreasonable Effectiveness of C

#185
post #136

Earlier quoted context omitted.

It may have been a high level language when it was a choice between ASM and C but the definition of "high level" has moved on. C is no longer a high level language. Just like diamonds are no longer at the top of the mohs scale. C is no longer anywhere near the top of "high" in "High level" languages.

C is and will (probably) always be a high level language by definition. That it's categorized as a lower level high level language than say Python or Ruby does not magically make it a low level language. There are low level languages which map mnemonics to instruction sets and high level languages that provide an abstraction over having to use the former and are more akin to the written word. That hasn't changed just…

A categorization that contains all but one language (Assembler) is not a useful categorization.

Besides, why die on this hill? So everybody suddenly concedes that, fine, C is a "high level language". Is anybody's opinions going to be changed? No.

So, how about we stick to useful definitions, and agree that in modern times C is a low-level language, and, likewise, understand that agreeing to that isn't going to change one letter of the C specification or remove one line of C's libraries or anything else?

There's no gain to be had by anyone in this silly line of argument.

Re: The Unreasonable Effectiveness of C

#186

Oh for heavens' sakes. Yet more ignorance. A more realistic view of C: - C is straightforward to compile into fast machine code...on a PDP-11. Its virtual machine does not match modern architectures very well, and its explicitness about details of its machine mean FORTRAN compilers typically produce faster code. The C virtual machine does not provide an accurate model of why your code is fast on a modern machine. The…

I agree with all of that.

Basically C is where it is because of a combination of timing and market forces. Market forces are usually underestimated by theoretical computer scientists, but they have a much stronger say in the success of a language than anything else.

However I still believe knowing C inside out is an essential skill, and as bad as it is, it's better than most of the alternatives for "low level" code. They usually either try too hard to be different or don't offer enough to substitute C and all the traction, coders, literature and codebase around it. And, as you mentioned, the fact that architectures became historically forced to play nice with C's machine abstraction.

Re: The Unreasonable Effectiveness of C

#187

Earlier quoted context omitted.

If you can't see the flaws in C you're probably writing poorly optimized, security-atrocious C.

I'm a professional pentester and I have been a C programmer for over well over 5 years, but I acknowledge that my C is probably still pretty bad :) how about you? :) P.S: now I have figured you out (on a very basic level of course) and I have a lot of respect, but nonetheless, let's play :)

I've been writing kernel code in C for about 8 years, including a hardware virtualization subsystem for use on HPCs. I used to teach Network Security and Penetration, but I lost interest in security and moved on to programming language development.

My code, in any language, is full of bugs. The difference is that in C my bugs turn into major security vulnerabilities. C is also a terrible language in that you never write C -- you write a specific compiler's implementation of C. If a strict optimizing compiler were to get a hold of any C I've ever written, I'm sure it would emit garbage. All the other languages I write code in? Not so much.

That said, is C useful? Hell yes.

Re: The Unreasonable Effectiveness of C

#188

Earlier quoted context omitted.

Well that is how memory, the hardware we have and also all normal operating systems work, but if you want to discuss other stuff we can do that too :) Try serious debugging and you will find that all your preconceptions are confirmed, yet it's still hard to know WTF is going on.

The "memory is just a giant array of bytes" abstraction hasn't been true ever since DRAM has existed (because DRAM is divided into pages), ever since caches were introduced, and certainly isn't true now that even commodity mulch-processors are NUMA with message-passing between memory nodes.

Fair point. At this point, it's a very leaky abstraction because not all levels of "random access" (e.g. L1 cache vs. main memory) are created equal.

Re: The Unreasonable Effectiveness of C

#189

Earlier quoted context omitted.

I'm pretty ignorant about this stuff, so please don't think I'm trolling. I'm confused when you speak of a virtual machine with regard to C... can you explain what you mean by this? I had to wikipedia the Burroughs machine. I guess the big deal is that it's a stack machine? It looks very interesting and I plan to read more about it. But I guess I don't understand why that is a hindrance to C. The JVM is a stack machi…

The Burroughs was a stack machine, but that's only the beginning. Look at how it handled addressing hunks of memory. Bounds checked memory block references were a hardware type, and they were the only way to get a reference to a block of memory. So basically, null pointers didn't exist at the hardware level, nor out of bounds writes to arrays or strings. Similarly, code and data were distinguished in memory (by high…

No, C does not define a single contiguous block of memory with consecutive addresses. It _does_ qualify that pointers are scalar types, but that does not imply contiguity or consecutive addresses (with the exception of arrays)

There is no requirement in C that you be able to execute data.

You certainly could have a C implementation that bounds-checks strings and arrays. (See e.g. http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html for a very old paper on how you might do that)

The "abstract machine" of C explicitly does _not_ make reference to the memory layout. (cf 5.1.2.3 of the spec)

It also makes no reference to the number of cores, and order of execution is not one at a time, but limited by sequence points.

That's the whole point of C - it is very loosely tied to actual hardware, and can accomodate a wide range of it, while still staying very close to actual realities.

Edit: Please don't take this as a "rah, rah, C is great" comment. I'm well aware of its shortcomings. I've spent the last 20+ years with it :)

Re: The Unreasonable Effectiveness of C

#190
post #60

I always get bashed for saying I like C++, but I genuinely don't get how C programmers manage without code like this: std::map > foo; One line and you've set up a nontrivial data structure with automatic memory management. No macro horrors (which are a diabolical way of implementing what C++ templates do well). Since you can code like C in C++, I'm not sure why more people don't use C-with-templates as a programming…

C guy here. I'm assuming you're serious and not being sarcastic... which is a nontrivial assumption, because that line you posted looks like something out of the foul depths of hell. You aren't going to run out of lines any time soon. Who cares whether your data structure definition is 1 line or 5?

> Who cares whether your data structure definition is 1 line or 5?

Why not use assembler and make it 50?

Post reply on HN