Live data from Hacker News

Pointers Are More Abstract Than You Might Expect in C

stefansf.de

181–190 of 267 posts

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

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

The C standard was (and is) written so that it allowed for machines that didn't have simple pointers; a highly relevant example for the time was x86 machines in real or protected mode using segment registers. Even when such environments have accessible linear address spaces under the hood, comparing the absolute address of two pointers requires some extra work (you have to reassemble the absolute address from the segment + offset pair). In the grand tradition of allowing the most efficient implementation possible, the C standard says that implementations don't have to do this work; they can simply compare pointer values directly, provided that they insure that pointers to the same object work (eg use the same segment + offset pair, which they normally naturally will).

The standard was also written to allow for C interpreters, where you may not have an underlying linear memory model at all and all pointers are represented internally in some complex way (for example 'object ID + offset inside object'). Here you don't have any particular idea of 'an address' as a distinct thing and so you can't naturally compare two pointers to different objects in any meaningful way.

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

#182

This scratches the surface of why I hope C slowly fades away as the default low-level language. C sounds simple when you look through K&R C. C lets you feel like you understand the stack, ALU and memory. A pointer is just an integer and I can manipulate it like an integer. But the reality is filled with a staggering number of weird special cases that exist because memory doesn't work like a simple flat address space;…

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

> A replacement for C should try to be as simple as possible while fixing C [...]

I have a feeling that such a language will offer too little to offset the costs of switching

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

#183

Earlier quoted context omitted.

"That is said a lot, but what are actual desicions that are made to conform to the C model?" Among other things, special instructions to support a function call stack, which is very much specific to the C model. In Lisp the call stack is unnecessary because of the use of continuation passing style, which implies that all function calls are tail calls and mostly requires that everything be heap-allocated (many compile…

X86 does have array bounds checking now with MPX. Further everything you've mentioned is useful to all languages including the stack. Can you give an example of a negative trade off made for C?

In some languages a call stack is only useful as an optimization and some other form of control flow must be emitted for certain constructs that violate the stack paradigm (e.g. call/cc in Scheme, conditions/restarts in Common Lisp). C is also one of the only languages where general pointer arithmetic is necessary; in most languages used today more restricted forms of pointer arithmetic would be more than adequate.

I am not saying these are negative tradeoffs as far as the ISA goes, but it is absolutely the case that modern CPUs are designed with C (or some similar language) in mind.

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

#184
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

[deleted]

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

#186
post #15

Basically you have no guarantee where the pointer q is pointing to. Some compiler/static code analyzer will yell at you with this code.

isn't it guaranteed that is points sizeof(int) bytes higher than the address of b? Whether something useful is behind that address is another question

Depending on your architecture and compiler it could be that everything is 128 bit aligned, so you would had "empty holes" in your memory layout. (For example some dsp's)

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

#187
post #153

Earlier quoted context omitted.

What?! Since when did Burroughs had a C compiler? NEWP was and is more than enough, while being much safer.

Safety is a hardware feature of the Burroughs architecture. C is no less safe there than NEWP.

Sure it is, NEWP only allows for C style unsafely on UNSAFE blocks, clearly tagged by the system administrator as allowed for execution.

So not only is lack of safety expressed on the type system, something that C doesn't have, it also allows someone explicitly stating it is ok to risk its execution.

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

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

> Note that it says "happens to" immediately follow, not "is guaranteed to" immediately follow.

I read that more as "happens to be placed" by the programmer (as a conscious decision), not including mere happenstance. In other words, this refers to arrays and struct fields.

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

#189
post #3

Earlier quoted context omitted.

> the compiler needs to optimise ... wants to. There fixed that for you ;-) The weird special cases were largely(1) introduced recently by optimizer writers hijacking the standard in order to soften the semantics so that previously illegal optimizations would now be legal, by simply declaring the vast majority of existing C code as "undefined" and up for grabs. Which is why the Linux kernel, among others, has to set…

What changes are you thinking of? The only change with respect to undefined behavior I can think of off the top of my head is punning via unions, which C99 changed from undefined behavior to well-defined behavior.

According to

http://www.complang.tuwien.ac.at/kps2015/proceedings/KPS_201...

new undefined behaviors were added, and for significant bits.

I think the bigger issue is that compiler writers have taken "undefined" to mean complete liberty to do whatever the hell they want, even fairly far away from the actual location of the undefined behavior.

And it turns out that the C89 standard had a range of "permissible" actions on undefined behavior. To me "permissible" is restrictive, as in you are not allowed to do anything outside that range.

Newer standards kept that section (3.4.3) the same, word for word, except for changing "permissible" to "possible". To me, "possible" is not restrictive but illustrative.

Now you might think this is reading tea-leaves on my part, and you might be correct, but on the other hand that change of interpretation is exactly what happened. Compilers used to not do these things, and nowadays compilers do do these things, and compiler writers cite the standard as giving them permission. Also consider to what extent wording of standards is finessed and fought over, and that exactly this one word was changed, in a section that otherwise remained the same word for word.

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

#190
post #141

Earlier quoted context omitted.

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…

C is the common denominator for FFI for OS that happen to be written in straight C, which then mix the C ABI with OS ABI. That is not true in mainframes, Windows (ongoing replacement of Win32 with COM, it is lot of fun to do COM in C, more so UWP), Android (JNI, AIDL), Web (JavaScript/WebAssembly), iOS/macOS (Objective-C runtime), Fuchsia (IDL).

COM and WinRT are still based on the C ABI though. So anything that can do that, can do them - hopefully with more layers on top for convenience sake, of course...
Post reply on HN