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
Pointers Are More Abstract Than You Might Expect in C
21–30 of 267 posts
Re: Pointers Are More Abstract Than You Might Expect in C
#22This 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,…
Re: Pointers Are More Abstract Than You Might Expect in C
#23I 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…
Re: Pointers Are More Abstract Than You Might Expect in C
#24Earlier quoted context omitted.
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
There's a guarantee relative to the address of b. But there's no guarantee about the relative addresses of a and b themselves , i.e. where they are placed in automatic storage. So even setting aside the idea of optimizing the test away at compile time, there's no guarantee that the comparison result will be a specific value. a could be above or below b, and they are not necessarily adjacent objects.
> If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
So although most implementations might produce an address that's relative to b, that's not actually guaranteed by the spec unless it's `&b + 1`.
Re: Pointers Are More Abstract Than You Might Expect in C
#25This 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,…
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.
Re: Pointers Are More Abstract Than You Might Expect in C
#26This 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;…
But as you know, CPU ISAs are designed for C programs and compilers are optimized for C programs. So everything, even new languages like Rust, have to buy into C's model to some extent. Truly getting out from under C's shadow is going to be very difficult. Maybe better languages are a first step on that path but they are only a small step.
What would be good ideas in CPU design that aren't made since they are not compatible with C?
(I get it that CPUs have to support some common paradigms and use cases. For example, virtual memory / process isolation, maybe branch prediction things, or support for calling conventions. However, I don't think that is specific to C).
Re: Pointers Are More Abstract Than You Might Expect in C
#27Just a datapoint: VS2017 on Win10 x64 gives me 00AFF89C 00AFF894 0, which is what I naively expect.
Actually, you should not expect that, because you don't have a guarantee of ordering of the addresses of a and b on the stack. Now try with /O2 . (-:
With /O2 optimisation I get:
00B1F99C 00B1F9A4 0
Re: Pointers Are More Abstract Than You Might Expect in C
#28Earlier quoted context omitted.
There's a guarantee relative to the address of b. But there's no guarantee about the relative addresses of a and b themselves , i.e. where they are placed in automatic storage. So even setting aside the idea of optimizing the test away at compile time, there's no guarantee that the comparison result will be a specific value. a could be above or below b, and they are not necessarily adjacent objects.
From the C11 spec quoted in the article > If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. So although most implementations might produce an address that's relative to b, that's not actually guaranteed by the spec unless it's `&b + 1`.
Re: Pointers Are More Abstract Than You Might Expect in C
#29Earlier quoted context omitted.
Actually, you should not expect that, because you don't have a guarantee of ordering of the addresses of a and b on the stack. Now try with /O2 . (-:
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
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:\>cl /O2 pointereq.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26431 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
pointereq.c
Microsoft (R) Incremental Linker Version 14.14.26431.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:pointereq.exe
pointereq.obj
H:\>.\pointereq
00CFFA20 00CFFA20 1
H:\>Re: Pointers Are More Abstract Than You Might Expect in C
#30the comparison at the start is nonsense - there is no specification for the ordering or location of stack variables. by taking the address of these variables, you could see that they actually are the same value, and so intuitively you’d think they might be the same, but a different compiler might put them in different locations. or they may be elided entirely through optimisation. it’s far safer to fail the equality…
Writing code which assumed those pointers were equivalent would be bad, but this code doesn’t do that. Instead, it looks like the compiler assumes that the pointers won’t be the same and refuses to let you entertain the possibility at all.