Live data from Hacker News

Pointers Are More Abstract Than You Might Expect in C

stefansf.de

131–140 of 267 posts

Re: Pointers Are More Abstract Than You Might Expect in C

#131
post #117
post #99

Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow…

Because (a) pointers do not point to addresses, and (b) now you have to define the concept of addresses being equal in the language standard and haven't actually reached the goal. (-:

Indeed; pointers intentionally abstract away memory addresses and addressing, which, as the article states, can be much nastier business than the benign flat address space of i386 protected mode.

Re: Pointers Are More Abstract Than You Might Expect in C

#132

Earlier quoted context omitted.

The following is purely my opinion. Rust might have gone too far the other way. Yes it strives to be a modern language, with a lot of functional programming features and "OOP" done right (aka no inheritance, simply method polymorphism). To me Rust is more a C++ replacement than a C replacement. A replacement for C should try to be as simple as possible while fixing C weak typing mess with strong typing for instance,…

> To me Rust is more a C++ replacement than a C replacement. People make this comparison a lot, but it’s not fair. Rust is far simpler, in terms of number of features of the language, to that of C++. It’s fair to say that Rust is far more expressive than C, but this just represents an initial learning curve that is higher than C, but not as high as C++. The type system is fairly simple in Rust, but it can be used to…

The only thing I ask of any C-replacement languages is that they make it possible to describe ABIs, message layouts, and on-disk formats in detail. C historically does that well enough, though not really all that well (e.g., bitfields and enums have issues, and struct packing is not always easy to get right). There is a lot of value to this!

The ability to mix object code from multiple languages (FFI) is critical, and that's why C is the common denominator for FFIs.

Re: Pointers Are More Abstract Than You Might Expect in C

#133
> ...or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.

I was not aware of this special case. What's the rationale? Is there even a way in standard C to guarantee that two array objects are laid out in memory like that, with no padding?

Re: Pointers Are More Abstract Than You Might Expect in C

#134
post #96

Earlier quoted context omitted.

The following is purely my opinion. Rust might have gone too far the other way. Yes it strives to be a modern language, with a lot of functional programming features and "OOP" done right (aka no inheritance, simply method polymorphism). To me Rust is more a C++ replacement than a C replacement. A replacement for C should try to be as simple as possible while fixing C weak typing mess with strong typing for instance,…

> C aficionados often claim they love C because it's "simple"(it isn't) That's what they mean, they love C because you can't really do OO with it I do not think C programmers are anti OO. Infact, a lot of C patterns are modeled on OO (struct + function). I think the appeal of C is that you are able to write the fastest implementation any given algorithm, something that just isn't possible in most other languages.

I don't think struct + function is any more OO than tuple + lambda is. That's a very shallow definition of OO.

Re: Pointers Are More Abstract Than You Might Expect in C

#135

Earlier quoted context omitted.

> faster even than hand-tuned assembly I think you and I are working off different definitions of what that means, as my definition doesn't really allow for a faster implementation (unless there's some really spooky stuff going on in the compiler). I suspect you mean faster than a popular hand tuned implementation.

Obviously Zig's output (courtesy of its LLVM backend) can be expressed and distributed as assembly code, but it's not hand-tuned, it's compiler-generated. Whether the hand-tuned assembly code they used was the fastest out there, I'm not sure. I'd hope so, or they're being misleading. I might get time to re-watch the relevant part of the video - it's around the 21 minutes mark - https://youtu.be/Z4oYSByyRak?t=1292

My point is that all the fastest hand-tuned assembly has to do to match the compiled output is to do the same thing. The compiler has no ability to do anything a hand-tuned assembly cannot, by definition of how this all works.

So, saying it's faster than hand-tuned assembly doesn't really make sense, but saying it's faster than current optimal hand-tuned assembly could, but that also probably requires searching for a not-very-well tuned problem, as any optimization the compiler could apply is something that could be applied by hand in the hand-tuned assembly (even if it requires a lot of work to do so).

A general statement that might be made (and would also be very impressive) would be that it compiles to implementations that are on par with the current best hand-tuned assembly versions.

The small edge case where the original statement might be true is where some AI/ML/evolutionary techniques are applied and the assembly is faster in the generated output but we don't know why. That is, the speedups are not because of rules and heuristics, but derived by some complex process which we have little insight into, and thus can't manually replicate (which is what I meant by spooky stuff).

Re: Pointers Are More Abstract Than You Might Expect in C

#136
post #65

Earlier quoted context omitted.

That was the argument of C++ advocates in the 90s.

Considering that C doesn't have any good facilities for polymorphism, it's going to continue to be the argument of any language that succeeds C. Unless, that is, that successor language also doesn't have any good facilities for polymorphism, in which case we have Go as a fascinating real-world study in how people will incessantly demand them and deride the language for lacking them (which is saying something, conside…

I presume that you are defining C++'s virtual functions as "not a good facility for polymorphism". Why?

Re: Pointers Are More Abstract Than You Might Expect in C

#137
post #122
post #18

Earlier quoted context omitted.

From reading the spec it seems that is undefined behaviour for anything other than `&b + 1`. That is one past the end of b is fine but not `&b + 2` etc.

I wonder why someone decided that accessing "one past the end" should be fine

It's explained in the addendum to the article.

Re: Pointers Are More Abstract Than You Might Expect in C

#138

Earlier quoted context omitted.

I love Rust, but I don't think that using a subset of Rust is a real option at this point. You'd have to stop using other libraries and even the standard library for this - and while it's possible, it definetly won't make your life easier. Rust has a wonderful community, but it's mostly filled with enthusiasts who're actively using nightly, so if you try to do things in a more limited way, you'll be on your own very…

While many people use nightly, the statistics show that most use stable, with some using nightly in addition. You just hear about nightly more.

Is that still true for libraries? I think that's what he meant, not all rust users as a whole. My impression certainly agrees with him.

Re: Pointers Are More Abstract Than You Might Expect in C

#139
post #57

I like the behavior of the compiler here. There is no guarantee that a and b are next to each other in memory. That's why the comparison fails, the alternative makes is runtime/compiler/optimization level dependent which would be a total mess. As usual with those C bashing articles you won't run into trouble if you don't try very hard to write contrived code. I mean, the moment you see: int *q = &b + 1; on your scree…

> I like the behavior of the compiler here. There is no guarantee that a and b are next to each other in memory. That's why the comparison fails, the alternative makes is runtime/compiler/optimization level dependent which would be a total mess Yes, there is no guarantee that they are next to each other, but in this case they happen to be next to each other, and according to the spec as quoted in the article, two poi…

> > For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

> I don't see any way to read these as not requiring the pointers to compare as equal if the compiler happens to put a and b adjacent in memory in the right order and with no padding between them, other than resorting to something ridiculous like claiming that "follow" or "immediately" follow are not defined in the spec and so one object occupying that very next available address after another does not necessarily "immediately follow". This seems to be what the gcc developers went with to declare this is not a bug.

"These operators" in the spec refer to the (additive) pointer arithmetic operators, not the equality operator. So incrementing a pointer to int behaves as if the pointee were in an array of length one, but that does not mean any subsequent equality operator should consider the objects as arrays.

It's totally fine for the equality comparison to return false when the objects in question are actually not arrays.

Re: Pointers Are More Abstract Than You Might Expect in C

#140

Earlier quoted context omitted.

> To me Rust is more a C++ replacement than a C replacement. People make this comparison a lot, but it’s not fair. Rust is far simpler, in terms of number of features of the language, to that of C++. It’s fair to say that Rust is far more expressive than C, but this just represents an initial learning curve that is higher than C, but not as high as C++. The type system is fairly simple in Rust, but it can be used to…

The only thing I ask of any C-replacement languages is that they make it possible to describe ABIs, message layouts, and on-disk formats in detail. C historically does that well enough, though not really all that well (e.g., bitfields and enums have issues, and struct packing is not always easy to get right). There is a lot of value to this! The ability to mix object code from multiple languages (FFI) is critical, an…

I won't do this justice, so I'll point you to the Rust book on this subject: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe...

In short, at the moment, if you want a stable ABI, you must export an un_mangled C interface. This is easy enough. One of my favorite sites is this for FFI stuff: http://jakegoulding.com/rust-ffi-omnibus/

It covers a bunch of languages, and suggests techniques for overcoming any complexity in exposing higher order types.

Post reply on HN