Live data from Hacker News

The Development of the C Language (1993)

bell-labs.com

81–90 of 536 posts

Re: The Development of the C Language (1993)

#82
post #59

Earlier quoted context omitted.

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…

> Strict aliasing is one of the few tools we have to tell the compiler that aliasing will not occur.

I can see the argument, but there's a much better way to indicate what you want with your example:

    void f(int16_t* a, int32_t* b) {
      const int16_t a0 = a[0];
      for (int32_t i = 0; i 
Now a clean (well defined) compiler could do what you asked.

I've seen other people suggest that UB is a mechanism to have these magical backdoor conversations with the compiler to express optimization opportunities. I think that's absurd and reckless. Propose adding assertions or "declare" statements instead, and quit thinking of interpretive dance through a minefield as a method of communication.

Re: The Development of the C Language (1993)

#83
post #23

Earlier quoted context omitted.

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

Not the commenter you're replying to, but I suspect what they mean is that the C memory model is byte-addressable not bit-addressable. You can't point/refer to a specific bit in memory, instead you have to first read the byte and then select an individual bit using bitwise operations, much like most modern processors.

That has nothing to do with the C memory model, but how the CPU is structured. No modern CPU has an interface for bit-address accessing as far as I am aware...

C makes no assumptions about the size of a byte

Re: The Development of the C Language (1993)

#84
post #81

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

that's the linker, not the c compiler

Is this important? I treat compiler as *full* toolchain

I run compilation and expect sane error messages - saying that "oh, it's because of linker yada yada" doesn't solve my problems nor is valid excuse

Other language (compilers) do better.

Re: The Development of the C Language (1993)

#85
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…

> The C representation of memory (and all the pointer arithmetic) is not a real representation of your hardware, and this too is an abstraction. By and large memory is a contiguous array and the C representation closely matches what is actually happening, so I am curious about which platforms you have worked on.

A couple points:

- CPU memory subsystems are very complex these days and represent a lot of shared mutable micro-architectural state, which makes it hard to reason about. That's not linear and the C language does not offer concepts which represent that complexity. Short of some prefetching intrinsics.

- Pretty much all memory will be virtually addressed, pushing you even further from the concept of flat linear memory.

- Pointer provenance [0] binds memory to types and allocations which doesn't map onto the concept of linear memory and a pointer is just an offset.

[0] https://faultlore.com/blah/fix-rust-pointers/

Re: The Development of the C Language (1993)

#86
post #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 ...

Everything looks fine if you use hello world examples

Yet when reality kicks in, then you can spend 15mins trying to figure what the hells is going on

Re: The Development of the C Language (1993)

#87
post #47

Earlier quoted context omitted.

They are also not normally directly addressable by the CPU, you'll have to do some combining and splitting with separate instructions. Some CPUs are better at this than others.

I wouldn’t quite count it as bit-addressing, but x86, for example, can load bits directly into the carry flag using the BT instruction which can take a register or memory address as it’s first argument, with the bit being given as the second.

There have been all kinds of variations on that theme. One of the nicest is 'bit test and set' as an atomic instruction, that one enables a whole raft of nice stuff.

Re: The Development of the C Language (1993)

#88
post #59

Earlier quoted context omitted.

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…

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

     *(int*)0x12345678
If not, give it time. It was only a few years ago when you were allowed to use a union for that kind of thing. I really believe they'll eventually make everything except unsigned integers be UB.

"Oh, the code was never correct. You just got lucky before."

Re: The Development of the C Language (1993)

#89
post #80
post #68

Earlier quoted context omitted.

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 poss…

> Things like small string optimizations in C++ are simply not possible in C.

I don't think this is true, I've seen a bunch of libraries implement SSO in C:

https://nullprogram.com/blog/2016/10/07/

https://github.com/stclib/STC/blob/master/include/stc/cstr.h

https://github.com/mystborn/sso_string/blob/master/include/s...

Re: The Development of the C Language (1993)

#90
post #78

Earlier quoted context omitted.

> 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/ >

Option 1 only works if there is a sensible unified interface, and if you feel like spending the time making that for what could be just one line per target. And it just won't work for things that don't really "have an interface", i.e. conditionally adding an __attribute__((optnone)) to a function that a specific compiler version gets stuck in an infinite loop optimizing, or macros that expand to some _Pragma-s that apply to a loop following it for controlling unrolling/vectorization if available, or managing custom inlining configurations for functions based on the optimization/debug levels, or defining a type as either 32-bit or 64-bit depending on requirements, or redefining all printf & fprintf usages to something mingw-friendly.

Many of those could be solved by some other means, but C macros neatly encompass all of those.

Post reply on HN