Live data from Hacker News

C array types are weird

anselmschueler.com

111–120 of 148 posts

Re: C array types are weird

#111
post #51
post #47

Earlier quoted context omitted.

We are working towards this though and a lot of this already works: https://godbolt.org/z/EP3cP3qGs

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.

Re: C array types are weird

#112

Earlier quoted context omitted.

> Because C is an exceptionally unopinionated language. Compared to what? Anyway I find it hard to believe enabling suicide is a good thing

> Compared to what? ...for somewhat recent languages: Rust, Zig, Odin... (with differing intensity, but they all want to nudge the programmer into a certain direction of how to do things). > Anyway I find it hard to believe enabling suicide is a good thing "War is peace, Freedom is slavery, Ignorance is strength" ;) Seriously, if people want to write their programs in assembly code or whatever weird kink, just let th…

[dead]

Re: C array types are weird

#113

Interestingly the article doesn't mention two-dimensional arrays and they're curios because they bring a certain asymmetry with them. It always tripped me over the most in C because I otherwise find the language very "symmetrical". It often feels like in design of this language the beauty of expressing certain things took priority over readability or safety which I admire in a way. But somehow not in the case of the…

For 1), you can just write (&a[i])[j] .

Re: C array types are weird

#114

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…

Those decisions also make a lot of sense from the C-as-macro-assembler point of view (passing parameters puts values in the places defined by the calling convention, and taking parameters pulls them out) that has of course gradually faded over the year, being replaced by a rigorously defined (and undefined) abstract machine.

Re: C array types are weird

#116

The way C handles array decay to pointers always trips up beginners, but it's exactly what makes passing data around so lightweight. Good writeup on a classic quirk.

Agreed, I even find it surprisingly ergonomic. Thinking of data as offsets into memory is unusual coming from almost every other language, but once you grokk it it's actually quite nice.

I love C more than I should.

Re: C array types are weird

#117

Earlier quoted context omitted.

I mean, just like with 1 dimensional arrays, it depends on the context. Array memory is on the stack. 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. If your 2d array sits on the stack, then inferring memory layout is pretty easy. If you are dealing with pointer that was passed to a function, then you can't ass…

> 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 structures / arrays. You can implement sub-allocators.

2) Heap allocator does not need to store exact length of allocated object. For example, it could have several fixed-length slab allocators for smaller objects, select matching one during malloc() and use address range to find slab during free().

3) Array can be also on the stack (VLA or alloca()).

4) Arrays can be also on memory allocated outside of C library allocator (e.g. mmap()).

Re: C array types are weird

#118

Interestingly the article doesn't mention two-dimensional arrays and they're curios because they bring a certain asymmetry with them. It always tripped me over the most in C because I otherwise find the language very "symmetrical". It often feels like in design of this language the beauty of expressing certain things took priority over readability or safety which I admire in a way. But somehow not in the case of the…

> If you see a[i][j] it could mean two completely different things: > 1) ... a[i][j] == *((char*)a + i*M + j) // I added the char* cast to make it correct > 2) ... a[i][j] == *(*(a + i) + j) You may already understand this but: even in case (1), you still have a[i][j] = *(*(a + i) + j) (It has to - that's what operator[] means in C.) It's just that, in this case, `a + i` is applying pointer arithmetic to char[M]* so…

Too late to edit but I wrote pointer to char[M] as char[M]* when, of course(!), it should be written as char(*)[M].

Re: C array types are weird

#119
post #88

Interestingly the article doesn't mention two-dimensional arrays and they're curios because they bring a certain asymmetry with them. It always tripped me over the most in C because I otherwise find the language very "symmetrical". It often feels like in design of this language the beauty of expressing certain things took priority over readability or safety which I admire in a way. But somehow not in the case of the…

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?

Re: C array types are weird

#120

Earlier quoted context omitted.

[flagged]

> How fucking stupid do you think we are. Well in your case specifically, I'm really not sure tbh. > You think the authors of unix would have used c if they could have bootstrapped rust instead? Considering that Ken Thompson later helped building Go, which is pretty much an anti-Rust, I do indeed think that they wouldn't have gone with an overengineered boondoggle like Rust if they had the choice. Apparently Brian Ke…

I think we can build much better software with rust than we can with c.
Post reply on HN