Live data from Hacker News

Pointers Are More Abstract Than You Might Expect in C

stefansf.de

31–40 of 267 posts

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

#31

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…

Agree on the alarm bells with the pointer arithmetic.

Disagree that gcc is doing the right thing here. The clang behavior (different comment in this thread) is much more sane: if the pointers happen to be the same, they compare as equal. If the pointers happen to not be the same, they compare as not equal.

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

#32

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

You don't need to use any polymorphism (generics or traits) in Rust. You can use it as a pure structs and functions language like C (especially if you're not using the standard library). The argument in favour of at least some polymorphism is that it helps to minimise highly repetitive code that would be avoided in C through aliasing, type punning or other pointer conversion.

> You don't need to use any polymorphism (generics or traits) in Rust. You can use it as a pure structs and functions language like C

This just means that the Rust language does not have the feature of being simple. Of course, there are sane subsets of C++ also (e.g., do not use new/delete), but this does not mean that C++ is a sane language. The same goes for Rust, probably.

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

#33

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

You don't need to use any polymorphism (generics or traits) in Rust. You can use it as a pure structs and functions language like C (especially if you're not using the standard library). The argument in favour of at least some polymorphism is that it helps to minimise highly repetitive code that would be avoided in C through aliasing, type punning or other pointer conversion.

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

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

#34
post #29

Earlier quoted context omitted.

Maybe I'm misunderstanding you, but it's precisely because I have no knowledge of the stack frame's layout that I didn't expect the pointers to be equal. With /O2 optimisation I get: 00B1F99C 00B1F9A4 0

That's where you are going wrong. You have no guarantee that the compiler places a and b next to each other, let alone in a defined order with a at a higher address than b such that one integer width beyond the end of b you find a. Expecting one thing is wrong. You are expecting the one thing that the comparison always returns false. You should not expect anything . The comparison result could be true or false. H:\>c…

You are confusing "did not expect them to be equal", which is what the OP wrote, with "expected them to be not equal", which is what you are railing against.

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

#36
post #29

Earlier quoted context omitted.

That's where you are going wrong. You have no guarantee that the compiler places a and b next to each other, let alone in a defined order with a at a higher address than b such that one integer width beyond the end of b you find a. Expecting one thing is wrong. You are expecting the one thing that the comparison always returns false. You should not expect anything . The comparison result could be true or false. H:\>c…

You are confusing "did not expect them to be equal", which is what the OP wrote, with "expected them to be not equal", which is what you are railing against.

Ahem!

"which is what I naively expect."

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

#37
There's nothing surprising in the first example. Comparing the addresses of stack variables is undefined behaviour.

The second one is more interesting:

    extern int _start[];
    extern int _end[];
    
    void foo(void) {
        for (int *i = _start; i != _end; ++i) { /* ... */ }
    }
GCC optimized "i != _end" into "true". The kernel guys fixed this by turning "_start" and "_end" into "extern int*". I always thought [] was just syntactic sugar over a regular pointer, but seems like I was wrong.

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

#38

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

> memory doesn't work like a simple flat address space

Can you expand on that? I thought that modern (non-segmented) memory does work like a simple flat address space, at least from the perspective of userspace programs. Isn't all the weirdness only a result of compiler optimisations?

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

#39
Note that if the two pointers are passed to a function, and the comparison is done in the function, the results are different:

  #include 

  void pcmp(int *p, int *q)
  {
      printf("%p %p %d\n", (void *)p, (void *)q, p == q);
  }

  int main(void) {
    int a, b;
    int *p = &a;
    int *q = &b + 1;
    printf("%p %p %d\n", (void *)p, (void *)q, p == q);
    pcmp(p, q);
    return 0;
  }
That is giving me:

  0x7ffebac1483c 0x7ffebac1483c 0
  0x7ffebac1483c 0x7ffebac1483c 1
That's compiled with '-std=c11 -O1' as in the article. The result is the same of pcmp is moved into a separate file so that when compiling it the compiler has no knowledge of the origins of the two pointers.

I don't like this at all. It bugs me that I can get different results comparing two pointers depending on where I happen to do the comparison.

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

#40

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

These architectural bizarrities exist and have to be dealt with by someone. Of course it is better if that someone isn’t you—if some rust maintainer ports the language to the obscure hardware where the CPU ignores the lower four bits when addressing and presents nice, neat, and performance abstractions for you to use.

But who is going to pay for that effort? If the hardware manufacturer cared enough to to invest a lot in developer tooling it probably wouldn’t have picked such a hostile interface to begin with.

Post reply on HN