Live data from Hacker News

How to Think About Variables in C

denniskubes.com

31–40 of 66 posts

Re: How to Think About Variables in C

#31

Extremely uninteresting- It is like a page of "C-S 1XX: Intro to C" fell out of its bindings and landed on Hacker News. This might have been mildly interesting if there had been the assembly for a few different architectures (x86, MIPS, ARM, PowerPC, etc) showing how the C code was translated to assembler for each. And could have been very interesting with an additional discussion of memory barriers and atomic operat…

I was trying to describe a simple mental model that has been helpful to me. While I agree assembly details would have been interesting putting that in would have lost more than half the audience.

> putting that in would have lost more than half the audience.

I surely hope not.

Re: How to Think About Variables in C

#32

Extremely uninteresting- It is like a page of "C-S 1XX: Intro to C" fell out of its bindings and landed on Hacker News. This might have been mildly interesting if there had been the assembly for a few different architectures (x86, MIPS, ARM, PowerPC, etc) showing how the C code was translated to assembler for each. And could have been very interesting with an additional discussion of memory barriers and atomic operat…

Amendment: 'Extremely uninteresting' -TO YOU-.

As someone who has had difficulty picking up real programming languages, and has only found some marginal success due to Obj-C's ARC feature, I can tell you this puts everything I've read in to much better perspective.

Try not to be so negative, man, I think it's clear you weren't even the intended target anyways.

Re: How to Think About Variables in C

#33
post #18

Extremely uninteresting- It is like a page of "C-S 1XX: Intro to C" fell out of its bindings and landed on Hacker News. This might have been mildly interesting if there had been the assembly for a few different architectures (x86, MIPS, ARM, PowerPC, etc) showing how the C code was translated to assembler for each. And could have been very interesting with an additional discussion of memory barriers and atomic operat…

HN has a pretty broad audience and a pretty big chunk of it doesn't know $language. These types of beginner posts for $language pop up from time to time. It's nothing to worry about.

Posts on elementary topics (should be) noteworthy only if mastery is exhibited. Hence, griping.

Re: How to Think About Variables in C

#34
post #5

Extremely uninteresting- It is like a page of "C-S 1XX: Intro to C" fell out of its bindings and landed on Hacker News. This might have been mildly interesting if there had been the assembly for a few different architectures (x86, MIPS, ARM, PowerPC, etc) showing how the C code was translated to assembler for each. And could have been very interesting with an additional discussion of memory barriers and atomic operat…

I agree. I liked the opening line though: "C is memory with syntactic sugar." It is a good introductory article for someone who has never used C -- CS-1xx Intro as you said.

"Syntactic sugar" generally means a syntax that's just a nicer-looking version of something that can be equivalently expressed in a more fundamental syntax. But C is more than that: it provides a way of abstracting away the details of the machine so that you don't have to explicitly deal with the fact that your machine has 64-bit pointers and 2's complement integer arithmetic and IEEE floating point and an instruction set that handles shift operations in a particular way.

So a better formulation might be: "C provides an abstraction layer on top of a computer's memory model and instruction set that will allow your code to be portable between different machine architectures, but only if you play strictly by the rules."

By the way, the classic K&R book explains the fundamentals of C pretty well. If you really want to understand C, I'd recommend reading it cover to cover (it's pretty short).

Re: How to Think About Variables in C

#35
It sounds simple, but you'd be surprised how many programmers don't grok the fact that types/data have sizes (especially numeric types). For many tasks, this doesn't matter, but when it does matter, you need people who understand.

As an example, an IPv4 address is 32 bits. Don't convert it to a string and put it in a varchar(64) in your database when you are optimizing for space (I actually saw this once). And yes, the DB had an inet type, but no one knew how to use it, what it was or why it mattered.

Re: How to Think About Variables in C

#37

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

If a variable were just a memory address and assignment were just a memory copy, this would be a valid operation.

It's a valid operation regardless of whether a standards body says it's not.

  uint32 x = 5;
  uint16 y = *(uint16*)&x;
The effect is to set y to the first two bytes of memory from x. Values assigned to x are serialized into memory in either big endian or little endian order. Those are the only two cases you have to account for. Quake 3 engine has a macro for the above operation which produces the same value of y on all platforms. This is useful for serializing x to disk, then loading it later (and possibly on a different architecture).

One source of confusion is that int and short are essentially, for all intents and purposes, undefined -- they are of course defined by the standards, but their implementation is allowed to vary so much that no programmer can make any assumptions about their size (in bytes) at runtime.

int8, int16, int32, int64 are all explicit and force the compiler (and the hardware) to obey the wishes of the programmer. This is, I think, the right approach. People make much ado about the fact that "a byte isn't necessarily 8 bits" and "the only assumption you can make about a short is that it's smaller than an int, and larger than a char", etc, which is probably unnecessary mental effort.

"Bytes are 8 bits. Here are four bytes. Here's the value that the four bytes store. Copy two of the four bytes to this other spot (adjusting for endianness appropriately via a macro)."

You typically don't want a memcpy in situations like this due to endianness.

The reason it's useful to explicitly "break the rules" like this is because it's important to know what assumptions you in fact can rely on, regardless of what standards bodies have to say about it. Because at that point you can do incredible things such as http://www.codercorner.com/RadixSortRevisited.htm

   inline float fabs(float x){
        return (float&) ((unsigned int&)x)&0x7fffffff ;
   }
The reason this is incredible and awesome (rather than horrible and dangerous) is because it enabled game developers to achieve a more impressive product for end users, because they were able to do more with the CPU resources that were available at the time.

It's of course not so relevant nowadays, since it's reasonable to assume that most gamers have at least a core 2 duo. But it's one of those things that isn't relevant until suddenly it is -- you're in some situation that requires sorting millions of floats, and your dataset simply demands more performance than your compiler typically gives you. Then suddenly you find you can do amazing things like this, and surprise people with how effectively you can use a modern CPU.

(Although, the modern antidote to "I need to sort millions of floats quickly" is to use SSE, not to sort floats as integers. Yet that's even more evidence that it's better to understand the capabilities of the hardware.)

Re: How to Think About Variables in C

#38

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

As the lab TA for a first year course in Java, I don't know how many times I repeated "A variable is like a box: it has a label (the variable name), and it stores something." - it's a simplistic analogy, but not far wrong (at least for Java), and it helps the new programmers get the idea.

Re: How to Think About Variables in C

#39
> C is memory with syntactic sugar and as such it is helpful to think of things in C as starting from memory.

http://en.wikipedia.org/wiki/Lie-to-children

> A lie-to-children, sometimes referred to as a Wittgenstein's ladder (see below), is an expression that describes the simplification of technical or difficult-to-understand material for consumption by children. The word "children" should not be taken literally, but as encompassing anyone in the process of learning about a given topic, regardless of age. [snip] Because life and its aspects can be extremely difficult to understand without experience, to present a full level of complexity to a student or child all at once can be overwhelming. Hence elementary explanations tend to be simple, concise, or simply "wrong" — but in a way that attempts to make the lesson more understandable.

OK, the very first sentence of this piece falls flat on its face when you begin to think about how a computer actually handles getting data into and out of the parts of the CPU that actually do the work of modifying data according to the opcodes in flight.

In specific, C is meant to be a pleasant syntax to sling data around a large, flat address space, where the assumption is that every part of the address space can be treated like any other, with no special consideration given to some locations being faster than others. (The 'register' keyword mucked with this a bit, but approximately nobody uses it anymore in new code. Just as well, because good compilers ignore it anyway; more below.)

This is horribly, hilariously wrong when you learn about cache hierarchy, and becomes even more wrong when you throw an OS implementing virtual memory and a disk cache into the picture. C doesn't have any way to refer to cache; you can't tell the compiler 'store this in cache' because that would break the abstraction C enforces.

So we loop back around: C enforces the abstraction for a good reason; namely, compilers are better than humans at scheduling memory use in practically every case, and in the few cases they aren't, you're doing something hardware-specific enough you'll need to drop into assembly anyway. This is also the reason the 'register' keyword is a no-op and has been for decades. Compilers can schedule registers better than humans because compilers know more about all of the optimizations in play, and when they can't, you'll have to drop into assembly anyway.

TL;DR: This is a basic introductory post. Nitpicking it for things that compilers take care of for you anyway is pointless.

Re: How to Think About Variables in C

#40
post #18

Extremely uninteresting- It is like a page of "C-S 1XX: Intro to C" fell out of its bindings and landed on Hacker News. This might have been mildly interesting if there had been the assembly for a few different architectures (x86, MIPS, ARM, PowerPC, etc) showing how the C code was translated to assembler for each. And could have been very interesting with an additional discussion of memory barriers and atomic operat…

HN has a pretty broad audience and a pretty big chunk of it doesn't know $language. These types of beginner posts for $language pop up from time to time. It's nothing to worry about.

$language in this case is C, the lingua franca of computing.

It is almost always the first language ported to any system, almost every computer science program at least covers the basics, it has been in 1st/2nd place on the TIOBE index for over a decade, its the 5th most popular language on github by commits and it is over 40 years old.

But- I'm willing to accept there might be people on Hacker news that don't know C, thats why I gave suggestions to the author to expand on the content and make it interesting to a wider audience. That was the point of my post.

Post reply on HN