
C Pointers Explained, Really (2012) - dizzystar
http://karwin.blogspot.com/2012/11/c-pointers-explained-really.html
======
greenyoda
Note that "%x" is not the correct way of displaying the value of a pointer
with printf(), since "%x" assumes that it's printing an unsigned int and a
pointer may be longer than an int (e.g., on a 64-bit architecture a pointer
would be 8 bytes and an int would typically be 4 bytes). The correct format to
use to print a pointer in hex is "%p", which knows how long a pointer is on
the current system.

For more details on printf() formats, see:

[https://en.wikipedia.org/wiki/Printf_format_string](https://en.wikipedia.org/wiki/Printf_format_string)

~~~
unwind
Actually %p can only be used to print values of type void * . Since there is
no requirement that other pointer types be converted to void * when calling a
varargs function, you need to cast:

    
    
        int x = 4711;
        printf("x is at %p\n", (void *) &x);
    

Of course the conversion will be a null operation on many modern systems,
where all data pointer types are implemented identically, but this is what the
language standard requires.

~~~
simias
Interesting, I thought pointer representation could only be different for
function pointers. Has there ever been an architecture where data pointers
could have a different representations?

~~~
nuxi
Yes, different representations as well as non-zero null pointers. More from
comp.lang.c FAQ at
[http://c-faq.com/null/machexamp.html](http://c-faq.com/null/machexamp.html).

~~~
simias
Ah, very interesting, thanks!

------
jeffreyrogers
When I was learning C I had heard about how terrifying pointers were and so I
expected them to be super difficult to learn. Maybe, my experience is
atypical, but I found them pretty intuitive.

~~~
cyphax
I have a similar experience but I have to admit that pointers became
reasonably trivial once our teacher told us to use pen and paper (or a digital
equivalent) to schematically draw how these pointers work, much like this
article does. The difficulty with pointers is, for me, keeping track of them
in your head, especially when you work with arrays. Otherwise it's actually
pretty straightforward!

~~~
lumpypua
> The difficulty with pointers is, for me, keeping track of them in your head,
> especially when you work with arrays.

I think this is mostly an artifact of C's type system. I wish pointers were
taught in a language with similar runtime semantics as C with a more
expressive type system. Drawing it out helps a ton, but the way C forces you
to embed that structure into code doesn't help.

------
simula67
When used within the context of pointers, it helps to think of '*' as the 'at
address' operator and '&' as the 'address of' operator. Especially when
reading code.

~~~
wnoise
A shame they didn't use "@" for the dereference operator...

~~~
Dewie
Wouldn't that also have made parsing simpler?

------
saosebastiao
Just came to say I think it is impressive this guy has an email from 1990
backed up.

------
kazinator
Is this really from 2012? Examples are in 1978 "K&R1" C:

    
    
      func(p)
      int *p;
      {
        body ...
      }
    

No, memory is not one big array, sorry. Objects have boundaries even though
there are valid addresses below their base and above their last byte. Not
everything that looks sensible from a machine language point of view is well-
defined.

Comment below article:

> _Marin Todinov said..._

> _Dear Programming Guru_

> _You are an absolute legend, ive been programming for 4 years and i have a
> masters in computer science, your explanation of pointers has helped me
> increase my efficiency in recursive functions and made a map in my breain of
> how these basic fundamental structers._

Lol, what the heck? Troll or astro-turfed? Where can you get a CS Master's
Degree and on only four years of programming?

~~~
angersock
_No, memory is not one big array, sorry._

No, no, memory _is_ in fact one big array of bytes. Everything else is just
really nice syntactic sugar over that fact.

Now, it may well be that attempts to _access_ that memory result in page
faults or weird interrupts or IO behavior or what have you, but the computer
_really does_ only see a big array.

~~~
MaulingMonkey
> but the computer really does only see a big array.

Define "the computer" in this context.

Certainly not the x86 chip itself - it sees memory as a series of caches (L1,
L2, L3) and eventually the memory bus, which it manages through various lookup
tables (TLB etc.) more closely resembling a series of hash tables on steroids
than an array - and that's ignoring per-processor caches on multiproc systems
and all the invalidation logic that needs to occur as a result.

What about processes? One flat memory space! ...except when you communicate
with another process, say by sharing memory. Then you realize you can't share
your 'indicies' without associating them to other indicies, because even if
the physical memory is the same, each process has their own 'array' for
indexing into that memory (and yours doesn't even contain everything in
theirs.) That's at least 68 arrays on my computer at the time of writing this,
not one.

The kernel's the one managing this mess of arrays, pinning pages needed for
interrupt handlers and software TLB support (for not even it is addressing
pure physical memory most of the time?)

I guess you could argue that because your chip supports DMA, you can do all
your array indexing through that to get to your 'one true' physical memory
addressing scheme, label that as what your computer 'really sees', and ignore
the 99.99% of instructions executing and making up the bulk of your
computation, which have nothing to do with that addressing scheme, but that
seems a bit disingenuous.

~~~
angersock
From C and assembly, that's very much how memory is access--compared with the
objects notion mention in the GP.

The fact that certain accesses may cause memory layout to change or other
strange things is something better left to the computer engineers. :)

