Live data from Hacker News

C array types are weird

anselmschueler.com

121–130 of 148 posts

Re: C array types are weird

#121

There is a history to it; in one of the predecessor languages, like B, Ritchie actually had arrays that had a hidden pointer to their start. The "array to pointer decay" was actually a real operation that loaded an address from memory, and it was possible to twiddle the bits to relocate an array. One problem with it was no way to initialize such a pointer field that would allow an array to live in dynamically allocat…

Not just this it is important to remember that there was no "aha!" moment where C was created whole-cloth by writing the first compiler in B then cross-compiling. The language B was evolved in-place by adding new features, then editing the compiler source to make use of those new features, then repeating. They simply started calling it "New B". At some point the language had evolved sufficiently that they decided to…

> Part of me suspects this was also because it was seen as "clever" at the time. Look ma, we let arrays turn into pointers! Isn't that clever?

It was intentional and functional. The idea was basically a primitive kind of polymorphism, which allowed for functions intended to act on arrays to accept any size of an array to be passed in. It was redundant with pointer arithmetic, but allowed for communication of intent without accidentally incurring a semantic unit of meaning. There's an interview where Ritchie talked about this.

Pascal's biggest misgiving was that it went the complete opposite route, where pointer arithmetic was disallowed and arrays did not decay. It also lacked any kind of polymorphism, and one of the biggest ergonomic painpoints ends up being that if your problem domain has non-uniform array sizes, you're in for a lot of annoying re-writing.

> When you look at pre-ANSI C function prototypes you wonder "where are the parameter types?" because there are none.

Actually pre-ANSI C technically didn't have function prototypes, ANSI C introduced them and it got them from C-with-classes. It did have function declarations though (which aren't the same thing)

Pedantics aside,

    f(a, b) { return a + b; }
This is fully typed, the parameters and return type default to int.

Fun fact:

    int f();
Does not declare a function with no parameters, but it does declare a function with an unknown number of parameters of unknown types. An empty parameter list in C is:

    int f(void);

Re: C array types are weird

#122

Earlier quoted context omitted.

> Array memory is on the stack. Array memory can sit on either the stack or the heap. > The size of that array is actually not known at run time, its only known at compile time, where any reference to that length gets resolved by the compiled. This is also a bit misleading, in two ways. First, it's not clear what you mean by "size" here - the size of the memory block(s), or the shape of the array? Second, many people…

> Second, many people think that the C runtime doesn't know the amount of memory allocated to an array, but this is actually false. It's just the C abstract model that for some reason chose to not expose this information. There are some counterpoints: 1) Conceptually, allocated memory block and data structure / array in it are not related. You can allocate memory block and then subdivide it to multiple different stru…

All are fair points, I was being a bit cavalier with the facts. I'll also add that many if not all modern malloc() implementations actually allocate somewhat larger amounts of memory than your request, to respect various alignment requirements and/or to avoid excessive fragmentation - even when not using pure slab allocations.

I do think the C++ bookkeeping from new[]/delete[] however has few if any similar caveats - the runtime really needs exactly the kind of information you also need in your code; the only caveat I can imagine is that it might omit this information for types that don't need destruction, such as `int`, but I don't know if this is a plausible optimization in realistic use cases that are not trivial.

Re: C array types are weird

#123
post #51

Earlier quoted context omitted.

The vec macros currently there directly call realloc()… that's gonna exclude any custom allocator setups… and the string code uses the vecs :/

The allocator interface is defined via these names. Just supply your own realloc. Of course you need to satisfy the constraints of realloc guaranteed to the compiler, or you need to invoke it in freestanding mode.

That doesn't work for pool allocators like https://apr.apache.org/docs/apr/1.5/group__apr__pools.html and neither does it work for our allocator https://docs.frrouting.org/projects/dev-guide/en/latest/memt... that takes an allocation group argument.

Re: C array types are weird

#124
post #69
post #42

Earlier quoted context omitted.

And yet so few other languages attempt to have a stable ABI (other than by...mimicking C).

C doesn't have a stable ABI, most folks mistake the ABI from OS written in C, with an imaginary C ABI.

Sure that's technically correct, but in practice it means I get a stable ABI :).

Re: C array types are weird

#125
post #42

Earlier quoted context omitted.

And yet so few other languages attempt to have a stable ABI (other than by...mimicking C).

The ABI is not the issue.

It's an issue if you want different software components to talk to each other without IPC.

Re: C array types are weird

#126
post #89

Earlier quoted context omitted.

At your service! D fixed it, and I'm sorry C users have suffered as the array-to-pointer decay blasted their kingdom. Fixing it in C is easy and should be the #1 priority.

At this point, C's #1 priority is not breaking things in existing implementations, though, Walter...

My proposal does not break existing code.

https://www.digitalmars.com/articles/C-biggest-mistake.html

Re: C array types are weird

#128
post #88

Earlier quoted context omitted.

And just in case you have not come across this, C++ allows you you overload all the relevant operators here: [], *, -> So, you really can't tell what's going on behind the scenes. I wanted to pull my hair out seeing some 'enterprise' code use state[i] = foo; for some kind of logging where i was the severity level. There were even instances of state[i++], where the severity was incremental. I hope someone has rewritte…

So you would be equally critical of overloading [] for maps? Sorry, hard for me to relate, as I've overloaded [] (in, say, Python) to make life easy on everyone. People loved it. I hope you're aware that there is a long standing debate on whether overloading operators is good/bad, and it comes down to personal preference?

> So you would be equally critical of overloading [] for maps?

No, I'm not sure how you got that impression. Overloading is great.

It's also confusing when it does something completely different from what you intuitively expect.

Re: C array types are weird

#129
post #103
post #87

Earlier quoted context omitted.

> The compiler may also flatten a loop. http://c2.com/cgi/wiki?SufficientlySmartCompiler In practice, C compilers are still notoriously bad at loop optimizations. Polyhedral optimizations provided some hope, but no compiler managed to adopt it in production.

Maybe, but also irrelevant to the discussion because whether you write mat[b * A + a] by hand or mat[b][a] and let the compiler frontend expand then makes no difference to the optimizer.

You missed the point.

Those two representations are equivalent, yes. But that's not what flattening loops mean.

Re: C array types are weird

#130
post #26

C array types are weird because C doesn't really need arrays. It's not what C was about. But if you designed a language in the era where Fortran, THE array language, reigned supreme, nobody would use your language. The mindshare Fortran had is difficult to convey now, half a century later. Think of it like making a chatbot today and not mentioning AI or LLMs, that's what making a language without arrays would have fe…

i learned FORTRAN in an accelerated tech program in 1996-ish in high school. i used fortran recently to see how "slow" python is, i did matrix multiplies by hand in .c, and .py. Now i didn't write the fortran, the AI did, but i remember enough that i verified what it did was sane, also the other two i wrote did agree with results. fortran 1 unit of time C 1.7 unit of time python 2.2 unit of time for the same matmuls.…

Fortran compilers will happily tile your loops.

C compilers don't really do this.

Post reply on HN