Live data from Hacker News

How to Think About Variables in C

denniskubes.com

21–30 of 66 posts

Re: How to Think About Variables in C

#21

What other mental models do people use to think about variables and memory? I would like to hear about them.

My mental model for C is symbol-referent diagrams like the first picture on http://www.exforsys.com/tutorials/c-language/c-pointers.html

If you keep track of which boxes are and are not runtime memory cells, that should be enough to work out any particular C pointer problem except the pointer-array almost-equivalence mess.

Re: How to Think About Variables in C

#22
> Every variable is a starting memory address to the compiler.

Definitely not true. More like, "it will have an address, if you take the address with the & operator". Otherwise, the compiler is quite free to store locals in registers.

Re: How to Think About Variables in C

#23
post #21

What other mental models do people use to think about variables and memory? I would like to hear about them.

My mental model for C is symbol-referent diagrams like the first picture on http://www.exforsys.com/tutorials/c-language/c-pointers.html If you keep track of which boxes are and are not runtime memory cells, that should be enough to work out any particular C pointer problem except the pointer-array almost-equivalence mess.

That is nice. I have seem different pointer diagrams but none that linked it to a memory list as that does. I like.

Re: How to Think About Variables in C

#24

> Every variable is a starting memory address to the compiler. Definitely not true. More like, "it will have an address, if you take the address with the & operator". Otherwise, the compiler is quite free to store locals in registers.

> Yes I am being simplistic and yes certain data types have certain syntactic sugar but I have found this to be a good mental model

As stated in the post.

Re: How to Think About Variables in C

#25

Earlier quoted context omitted.

My point is that pointer-or-not is irrelevant and muddies the issue. The problem is entirely that it's not an l-val.

I can agree on that. The point I was trying to make is that &x would return a number not an assignable memory location. The reason it isn't an lvalue is because it doesn't return a memory address the way a variable assignment or dereference would. I was probably a bit confusing in what I was trying to say.

It is quite confusing, because it implies that this is equivalent and equivalently wouldn't work:

    int *ptr = &x;
    ptr = 20;
The rvalue/lvalue distinction is completely unrelated to pointers, holding memory addresses versus numbers representing memory addresses, etc. The & operator simply doesn't give you an lvalue, like most operators in C, and this has nothing to do with addresses, pointers, or anything of the like

Re: How to Think About Variables in C

#26
There are some subtle problems with the model as explained in this article. If you use this as your mental model, you will probably run afoul of undefined behavior without realizing it.

If you read the C standard, you'll notice it doesn't talk much about "memory" (the word only appears 13 times in C99); it mostly talks about "objects" (mentioned 735 times in C99). These objects aren't OO-objects -- obviously C doesn't have OOP built in -- but rather all the basic types like int, float, struct, etc are objects. When you declare a variable like "int x", you are creating an object.

C's aliasing rules dictate that you can only access an object via a pointer of that object's actual type. This is why it is dangerous to think of the assignment operator as a simple memory-copying operation. If assignment were a simple memcpy, you could do something like this:

  int x = 5;
  // BAD: undefined behavior, violates aliasing.
  short y = *(short*)&x;
If a variable were just a memory address and assignment were just a memory copy, this would be a valid operation. But the right way to think of it is that a variable is a storage object whose address can be taken, and and a dereference is an operation that reads a storage object.

A pointer isn't a generic memory-reading facility, it must actually point to a valid storage object of the pointer's type (or to NULL).

If you do want to read and write arbitrary objects in memory, you can always use memcpy():

  int x = 5;
  short y;
  // This is fine, and smart C compilers optimize away the
  // function call.
  memcpy(&y, &x, sizeof(y));

Re: How to Think About Variables in C

#27
post #25

Earlier quoted context omitted.

I can agree on that. The point I was trying to make is that &x would return a number not an assignable memory location. The reason it isn't an lvalue is because it doesn't return a memory address the way a variable assignment or dereference would. I was probably a bit confusing in what I was trying to say.

It is quite confusing, because it implies that this is equivalent and equivalently wouldn't work: int *ptr = &x; ptr = 20; The rvalue/lvalue distinction is completely unrelated to pointers, holding memory addresses versus numbers representing memory addresses, etc. The & operator simply doesn't give you an lvalue, like most operators in C, and this has nothing to do with addresses, pointers, or anything of the like

After rereading it a couple times I think you and others were right. I was trying to say something that in the end muddied issue. I have removed the section on r-value and l-values.

Re: How to Think About Variables in C

#28

> Every variable is a starting memory address to the compiler. Definitely not true. More like, "it will have an address, if you take the address with the & operator". Otherwise, the compiler is quite free to store locals in registers.

> Yes I am being simplistic and yes certain data types have certain syntactic sugar but I have found this to be a good mental model As stated in the post.

This reminds me of another comment I had: I personally find the phrase "syntactic sugar" irritating. As used, I don't feel like it adds anything to the blog post. IMO you could write nothing there and it'd make the exact same point.

What exactly is the "syntactic sugar" that hides the idea that names can have addresses? Structs? Some specific kind of expression? Array index syntax? The names themselves?

Re: How to Think About Variables in C

#29

> Every variable is a starting memory address to the compiler. Definitely not true. More like, "it will have an address, if you take the address with the & operator". Otherwise, the compiler is quite free to store locals in registers.

> Yes I am being simplistic and yes certain data types have certain syntactic sugar but I have found this to be a good mental model As stated in the post.

Simplicity here doesn't help. Variables aren't about how they are stored and where but more about what gets applied to them and how.

Re: How to Think About Variables in C

#30

> Every variable is a starting memory address to the compiler. Definitely not true. More like, "it will have an address, if you take the address with the & operator". Otherwise, the compiler is quite free to store locals in registers.

> Yes I am being simplistic and yes certain data types have certain syntactic sugar but I have found this to be a good mental model As stated in the post.

I think you're going to keep getting comments on these ill-considered asides, but here is another problem:

"In most assembly languages, data types don’t exist. You operate on bytes and offsets."

This is just not true.

Most assembly languages (I learned on PDP-11 assembler, which I remember best, but what I say is true of 68000 and x86 too) have a notion of a byte, but also integers of various word lengths, and floating point numbers.

In fact, some registers are in effect designated as "pointers" for various kinds of conventional indirect addressing (the instruction pointer, the register holding the stack pointer, and others).

In this sense, C is even closer to assembly than you indicate, because the data types are so analogous.

Post reply on HN