Remix.run Logo
▲ phamilton 17 hours ago

Re: arrays are pointers.

One of my favorite things to show just how bare this is in C is to show array access commutativity.

  char c = {1,2,3}

  c[1] == *(c + 1)
  
  *(c + 1) == *(1 + c)
  
  c[1] == 1[c]
C is wonderfully simple at times.
▲pwdisswordfishq 16 hours ago | parent | next [-]

I have known about this for quite some time, and the more I think about it, the more useless it seems. Sure, the underlying machine operation is just addition, which is indeed commutative, but at the type system level, the pointer and the offset have distinct roles. It just makes no sense to allow to commute them, just like it makes no sense to allow to commute arguments to, say, strchr, just because the compiler can figure it out by looking at the types. When was the last time you had a practical reason to write "offset + pointer" or "index[array]"?

In most languages, the indexing operator is not commutative. In Rust, pointer offseting is expressed as a function call or a method, also not commutative. I have never seen a single complaint about either. It's not something people want or care about, it's just a tedious detail.

▲skydhash 16 hours ago | parent [-]

> It's not something people want or care about, it's just a tedious detail.

It’s not something idiomatic, but indexing in C is syntactic sugar. Not sure why they allow it in the syntax, but forgetting that arrays are pointers and not special type is just asking for bugs.

▲im3w1l 15 hours ago | parent [-]

Arrays are not pointers in c. Though they are very similar and will implicitly convert, there are differences. The big and obvious difference is that declaring an array will allocate space for it. In a function, on the stack. In a struct, inline. They have different sizeof. I think there are also some other stuff I can't remember.

▲ynik 13 hours ago | parent [-]

In C there's only two operations you can do with arrays that do not decay to a pointer: `sizeof(array_var)` and `&array_var`. The latter produces a rarely-seen "pointer to array", i.e. a type like `int (*)[10]` (pointer-to-array syntax works like pointer-to-function syntax).

▲creata 15 hours ago | parent | prev | next [-]

As fun as it is, 1[c] will be "marked obsolete" in C29 according to Wikipedia.

▲avadodin 24 minutes ago | parent [-]

C11 is last C as far as I'm concerned.

I don't mind adding new features in committees but if they are going to remove compatibility, they should rename their language to nuC or CantbelieveitsnotRust(yet).

No offense intended to Rust which is a fine language.

▲mr_00ff00 17 hours ago | parent | prev | next [-]

All fun and games with arrays being pointers, until you declare an array in a function and return it.

▲jackling 16 hours ago | parent [-]

Isn't this easily catchable with static analysis, -Werror -Wall? I've never had a practical problem with this.

Also arrays aren't pointers in C, they decay into pointers. You can see this since sizeof will work differently in the function that instantiates the array versus one that takes in the pointer as a parameter.

▲skydhash 16 hours ago | parent | prev | next [-]

> C is wonderfully simple at times.

Yesterday, I watch a quick video[0] where Matthew Butterick was comparing book sizes and their appeal. “The C Programming Language” was my second programming book (after one about JavaScript 1.x) and I still remember it fondly. Easy to start with (with CodeBlocks on Windows and gcc on Linux) and the concepts were nicely explained. The book were also very nice.

[0] https://www.youtube.com/watch?v=W-ryv6TwQvM

▲Ygg2 16 hours ago | parent | prev | next [-]

Isn't Lisp even more bare bones?

At end of day minimalism is a neat but not decisive feature. If minimalism was decisive we'd all be writing Brainfuck.

▲brabel 16 hours ago | parent | next [-]

Lisp minimalism is very different. It assumes a runtime with automatic memory management for example, even if the language concepts themselves are minimal, especially in Scheme, it has almost no syntax and just a few core facilities on top of which everything else is built, which are closely related to the Lambda calculus, kind of ignoring completely what real computers actually look like.

In C the minimalism comes from providing only the minimal set of things that are available in most (maybe all) architectures (the Von Neumann paradigm), like linear memory, a simple function calling convention, close mapping to Assembly operations etc. But C syntax is not very minimalist compared to Lisp , let alone Forth. The fact that C syntax became prevalent in the programming world seems to be mostly an accident to me, it’s not objectively better than those minimalist languages’ or Pascal’s, Prolog, ML families.

▲WalterBright 7 hours ago | parent | next [-]

> providing only the minimal set of things that are available in most (maybe all) architectures

The rise of C in the 1980s induced CPU makers to design instructions that cater to C semantics.

▲rramadass 4 hours ago | parent | prev | next [-]

> In C the minimalism comes from providing only the minimal set of things that are available in most (maybe all) architectures (the Von Neumann paradigm), like linear memory, a simple function calling convention, close mapping to Assembly operations etc.

This is beautifully illustrated in the old classic The C Companion by Allen Holub which overviews a simple abstract demo architecture and code generated for it. This is a small book (in the vein of K&R C) but contains enough illuminating info. for a programmer.

▲Ygg2 13 hours ago | parent | prev [-]

> In C the minimalism comes from providing only the minimal set of things that are available in most (maybe all) architectures

By that logic Brainfuck is even more minimal. Again. I'm saying minimalism isn't the goal. It's a good quality but not most important one.

▲KerrAvon 16 hours ago | parent | prev [-]

I would add on top of brabel's post that C is surprisingly difficult to parse correctly (C++ notoriously so).

Zoom out a little: C is a lot like Unix: simple probably isn't the right word; `underengineered` comes to mind. Which leads to complexity, as you need to make things work in the real world. And so Unix syscalls being designed in the early 1970's for a PDP-11 don't really map to modern needs. And so every unanalyzed complex C app has memory leaks.

To be clear, I like C, I like C++, I like Objective-C, I like Swift; I'm comfortable in all of them. But, in 2026, I don't see why for native code everyone shouldn't be programming in Rust / Swift / other modern memory-safe flavor for any new production use. Zig if you want faster compile times, I guess.

▲skydhash 15 hours ago | parent [-]

> But, in 2026, I don't see why for native code everyone shouldn't be programming in Rust / Swift / other modern memory-safe flavor for any new production use. Zig if you want faster compile times, I guess.

Because C is very simple (unlike Rust) and works everywhere. Zig is not yet stable. Go and Swift are under the governance of tech companies.

The true appeal of C for me is the standard and how it applies only to the language. You can easily take a project from 2 decades ago and port it to a current platform. Lot of current ecosystem is way too fussy about tooling to do this.

▲tialaramex 11 hours ago | parent [-]

> Because C is very simple (unlike Rust) and works everywhere

That's definitely true. C is a "Worse is better" language and as such it's everywhere. You can knock together a halfway usable C for some crap hardware in a few weeks and then the hardware is saleable because there's a C implementation.

> You can easily take a project from 2 decades ago and port it to a current platform.

Much of the software I wrote two decades ago in C won't even build today. Good luck figuring out why, periodically I try to figure out which weird 2000s era Mac OS hacks don't like a 2026 Linux system and eventually I give up and write modern software instead.

In theory C written in 2006 definitely "just works" on a 2026 Linux machine but in practice real world C is broken and even though I (co)wrote it I don't know why. Also in practice the first serious Rust project I wrote in 2021 I just found it, checked out the oldest working version ("first rough working code" says the log) from git, cargo run, works as expected.

Maybe it's because the C was four times older, but I think it's because in the real world you don't end up writing that mythical portable C code too often.

▲lelanthran an hour ago | parent | next [-]

> Maybe it's because the C was four times older, but I think it's because in the real world you don't end up writing that mythical portable C code too often.

It's because C, over time, went from a bunch of almost compatible implementations, to a standard that differed a little from every existing implementation, to a standard that is updated every decade or so, which is then implemented by a bunch of different products, with enough ambiguity in the standard (UB) that there will be differences between compilers and versions of compilers.

Rust is a single implementation. Always has been.

It's a single product, so you code to the product. The product has no external forcing function, like a language standard, that produces changes every decade. When you write Rust, you aren't thinking "Wait, lets make sure this works on the Watcom compiler too".

If Rust code cannot compile 30 years later, that's a failure on the language, because the single implementation is in full control of compatibility. If C code cannot compile 30 years later, that's not a failure of the language, because the implementation in 30 years has had external pressure forcing changes.

People often forget that Rust is a product, C is a specification.

▲fastaguy88 5 hours ago | parent | prev [-]

I have 'C' code that was written in 1985 that runs today, mostly after moving function parameters from inside the function to inside the argument list.

'C' seems to be a language that makes it easy to write incomprehensible statements, but it's not that hard (or it was not that hard) to write code that is trivial bring up to date. Perhaps it was easier for me because I started with Fortran.

▲fithisux 2 hours ago | parent [-]

Very common.

▲mathisfun123 16 hours ago | parent | prev [-]

[flagged]

▲junon 16 hours ago | parent [-]

Man just let people enjoy small things.

▲mathisfun123 16 hours ago | parent [-]

I don't know what you're implying - I asked a genuine question: what is impressive about that syntax.

▲1718627440 15 hours ago | parent | next [-]

It's not the syntax that's impressive. It's that most people who don't know C, likely wouldn't consider array access to be commutative.

▲cephi 10 hours ago | parent | prev | next [-]

It's not impressive, it's just a fun thing to show people who learned traditionally and never thought to question the commutativity of the syntax (or whether it is commutative at all)

▲junon 16 hours ago | parent | prev [-]

They never said it was impressive. Just that they like to demonstrate it, presumably to people who don't know about it.