Live data from Hacker News

The Development of the C Language (1993)

bell-labs.com

71–80 of 536 posts

Re: The Development of the C Language (1993)

#71
post #59
post #37

Earlier quoted context omitted.

> the C representation closely matches what is actually happening It really doesn't, though. Although your CPU might present system RAM as one contiguous array of bytes to your program, the C compiler follows different rules – see strict aliasing and other pointer dereference rules. For example, the following is Undefined Behavior and your C compiler may or may not generate the assembly you expect: int x = *(int *)0x…

The original author was talking about hardware not behaving like linear memory, and other than caches and maybe some thread local tricks, I'm not sure what he meant. However, it seems pretty clear that CPUs do try really hard to make: mov rax, qword ptr [0x12345678] do what you think it would/should. And as for the C memory model, aliasing, and optimizations, I'm firmly in the camp that thinks the standards originall…

> The point to me is that using memcpy instead of pointer casts is NOT an improvement.

The improvement comes when there are multiple accesses that could potentially point to the same memory. Consider a silly function:

    void f(int16_t* a, int32_t* b) {
      for (int32_t i = 0; i 
If type-based alias analysis is enabled, then the compiler can assume that a[0] does not alias b[i] because they are different pointer types. So it can hoist the load of a[0] outside the loop, improving efficiency. If strict aliasing is disabled, it cannot assume this, so it must reload a[0] each time: https://godbolt.org/z/E7jxfYsbx

The memcpy() makes it clear that the memory could alias anything, so it will generate the less efficient code even if strict aliasing is enabled: https://godbolt.org/z/KoPxK9fPj

Memory aliasing is a huge thorn in the side of the optimizer, because the compiler frequently has to allow for the possibility that different pointers will alias each other, even if they never will in practice. The code might end up being slower than necessary for no real reason. Strict aliasing is one of the few tools we have to tell the compiler that aliasing will not occur.

I don't think that C actually forbids this code:

     *(int*)0x12345678
The rule is just: if you access it as an int, you have to consistently access as an int. You can't mix types from one access to the next, eg:

    *(long*)0x12345678
    *(int*)0x12345678

Re: The Development of the C Language (1993)

#72
post #11

Earlier quoted context omitted.

> I don't think I've ever seen a computer where memory is actually a continuous array of bits sorted by memory address well, that is not the C memory model. C does not allow you to access bits in memory directly. maybe you meant bytes? or words? if so, many cpus have exactly that architecture.

> C does not allow you to access bits in memory directly. of course it does what are you talking about?

I wouldn't consider accessibility (via masking & shifting or struct bit fields) to be the on the same order as the byte-level addressing you get with pointers.

Re: The Development of the C Language (1993)

#73
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

There are a few reasons:

    The Lindy effect.
    You can run C code from anywhere.
    There are places where it is much easier and better to run C code than anything else.
All of these are related to how long C has been around. I think that's also the reason why we use JavaScript extensively.

Re: The Development of the C Language (1993)

#74

I just wish C had better compilers Errors produced by current mainstream compilers are terrible. "Unresolved symbol" being the best they can do is some joke

Uh? gcc (11) produces, eg

  /usr/bin/ld: main.o: in function `main':
  /cptutils/src/xycpt/main.c:148: undefined reference to `xycpt'
You get the file, the line, the name of the missing symbol ...

Re: The Development of the C Language (1993)

#75
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

> People who still write C, honest question: Why?

Because loops are fast.

I do scientific computing, where many people use python nowadays, and a few years ago it was matlab/octave. These languages feel "cramped" because they artificially force you to program in a certain way in order to avoid loops. While such a "vectorial" notation is often useful, many algorithms are better expressed using a loop notation, and C does not impose an artificial distinction between the two notations: both are as fast as they can be. The fact that python is not an appropriate language for low-level numerical computation is evident when you notice that most numeric algorithms in python are just interfaces to code written in other languages (C, C++ and Fortran).

Of course, C is not the right tool for the job either... Modern Fortran is, objectively, the ideal language for low-level numerical computing: it has native multidimensional arrays and a lot of other goodies, which C lacks.

Julia would also be a nice alternative, and I check it regularly. But I find the current interpreter too quirky. I would love to see different interpreters/compilers for this lovely language!

Re: The Development of the C Language (1993)

#76
post #27

Earlier quoted context omitted.

When I get to achieve my target 3 times faster using Go why should I waste my time following “functional ways” just to use to write project A

Rust is not "functional ways", though, and Go is certainly not devoid of annoyances (subjectively). Really wish people would stop having language wars and realize that languages are tools for a job. C is like a flathead screwdriver, C++ is like a philips, Rust like a torx and Go like a hex. You can probably use a flatheat or even a philips for the torx or hex screws but you probably shouldn't, because they're not the…

>Really wish people would stop having language wars and realize that languages are tools for a job. C is like a flathead screwdriver, C++ is like a philips, Rust like a torx and Go like a hex. You can probably use a flatheat or even a philips for the torx or hex screws but you probably shouldn't, because they're not the right tool for the job.

There are far more languages than types of jobs though. If it wasn't for language wars, how would you ever decide which one to use?? :)

Re: The Development of the C Language (1993)

#77

Earlier quoted context omitted.

> I used to think "C presents the most honest representation of the low-level mechanisms of the computer", but... even this is shaky. I've been programming for almost 15 years now, and I don't think I've ever seen a computer where memory is actually a continuous array of bits sorted by memory address. The C representation of memory (and all the pointer arithmetic) is not a real representation of your hardware, and th…

Why do programmers in 2023 need to imagine a virtual machine (basically a PDP-11 from 1970-something) at all? You only need that abstraction if you're doing low level bit/byte bashing and I/O, or there's some chance you may run out of memory and need to handle that manually. That applies to a tiny slice of all possible applications. There are far more useful modern abstractions that don't need to make those assumptio…

Yeah that's true, and that's why people don't use C for stuff that isn't close to the metal. If you're just serving some web page you can just think about the business logic and a higher level language will deal with the rest for you.

But someone's got to write drivers and someone's got to write the thing that connects the higher levels to the metal.

Re: The Development of the C Language (1993)

#78
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

> Add to this CPP macros, a universally recognized bad idea I don't think is not a bad idea. You can't solve language incompatibilities in the language it self. Textual macro languages solves this nicely. CPP is what makes C and C++ work for projects aimed at multiple platforms or compiler vendors.

Yes, you can. Two approaches:

1. Multiple implementations providing a unified interface, selected by the build system. Aka the Henry Spencer approach: https://www.usenix.org/legacy/publications/library/proceedin...>

2. Less-bad macros, e.g. cond-expand: https://weinholt.se/articles/cond-expand-and-ifdef/>

Re: The Development of the C Language (1993)

#79
post #12

Earlier quoted context omitted.

Because everything speaks C. If you write a library in C, it can be easily exposed to a variety of high-level languages and platforms. You might argue this is more a property of the C ABI than of C itself, but unless the project is large enough that it's worth doing it in C++ or Rust instead, it's still a very reasonable choice. Also not everything is web. Sure, if you're writing API endpoints in C you're just shooti…

So we're gonna be stuck writing a precambrian prototype language till the end of time because there's so much legacy code already written in it? Never seemed to stop people moving from Pascal, or Perl or literally all other languages that are now obsolete. I really hate how for microcontrollers the only two choices are either C++ or Micropython, I mean how about some fucking middle ground instead of two polar opposit…

> I really hate how for microcontrollers the only two choices are either C++ or Micropython

Why wouldn't you just use C for programming a microcontroller? Sure, it's not a great language for web backends, but microcontrollers are where it shines. You're probably not deploying 100,000 lines to a microcontroller for a personal project, so the lack of certain abstractions isn't going to be that painful. On the other hand, C lets you make the latency and memory usage 100% predictable, which can be a great asset.

Re: The Development of the C Language (1993)

#80
post #68
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

1. It gives me a lot of control over how the program works, which lets me create programs that work faster and use less memory than would be possible in most other languages. 2. Relatedly, it's more explicit than almost any other language. If a line of code doesn't look like a function call, it's not calling anything. There is no hidden control flow. These statements are not true in languages which support operator o…

> It gives me a lot of control over how the program works, which lets me create programs that work faster and use less memory than would be possible in most other languages.

While it is true to a degree, I would also add that due to its low level of expressivity, you often have to introduce less efficient solutions simply because language deficiencies. Things like small string optimizations in C++ are simply not possible in C.

2 is true, but it comes at the expense of bad expressivity, see the former point.

3. Well, will it really compile to what you meant? If you have UB, it might still compile but the semantics of your program could change entirely depending on which compiler and which version you use.

Also, your Python point: well, that’s because you used python in the first place, which is very slow even among scripting languages.

Post reply on HN