thomblake comments on Hand vs. Fingers - Less Wrong

25 Post author: Eliezer_Yudkowsky 30 March 2008 12:36AM

You are viewing a comment permalink. View the original post to see all comments and the full post content.

Comments (94)

Sort By: Old

You are viewing a single comment's thread. Show more comments above.

Comment author: ec429 14 September 2011 01:20:29PM *  8 points [-]

As a C programmer who hangs out in comp.lang.c, I'm strongly tempted to get out a copy of C99 so that I can tell you precisely where you're wrong there. But I'll content myself with pointing out that there is no guarantee that sizeof(long)==2*sizeof(short)==4*sizeof(char), and moreover that even if that did hold, there is still no guarantee that sizeof(struct {short hi; short lo;})==2*sizeof(short) because the struct might have padding - what if 'short' were a 16 bit quantity but stored in 32 bit words (perhaps because the arch can only do 32 bit writes, and has decided that short should be an int_fast16_t rather than an int_least16_t), resulting in alignment requirements?

In conclusion, PK should learn some basic C, and forget about the ++. (Old joke: what does C++ mean? Take C, add to it, then use the old version)

EDIT: thanks, paper-machine, and I approve of Markdown's choice of escape character. Now, if it'll just let me use \033[1;35m to change the colour...

Comment author: thomblake 14 September 2011 02:07:20PM 3 points [-]

I don't see anything wrong with grandparent, assuming a particular architecture. And whenever I used to write c, it was almost always for a particular architecture, usually with inlined assembly. Am I missing something, or are you just trying to make some point about portability regarding a metaphor?

Comment author: ec429 14 September 2011 04:41:55PM *  4 points [-]

It is a lesson hard-learned over many programmer-years of coding that portability should be acquired as an innate reflex; that whenever you are about to sacrifice portability, you ask yourself "Why am I doing so, are there alternatives, and have I done at least a rudimentary cost/benefit analysis of this decision?"

What you don't do is throw away portability just because you happen to be using a particular machine right now. This is something quickly learned in comp.lang.c.

Incidentally, a better model than PK's might be:

typedef struct foo {int i} s;

s f;

Now what is 'f'? Is it an 's', is it a struct foo, or is it an int? And what about f.i? Both have the same address, casting either's address to any of the pointer types 's *', 'struct foo *' or 'int *' is valid; writing

*(int *)&f=1;

does just the same as f.i=1; quite possibly the compiler will generate the same code, because after all, the territory is the same. It's just that "f.i=1" is a higher-level map, which conveniently abstracts things out.

This is made more explicit by considering struct bar {int a; long b;} t; *(long *)(((char *)&bar)+offsetof(bar, b))=1; // same as bar.b=1

Of course, you could go to all the trouble of computing the offset pointer every time, since that's what happens on the "quark" (assembly language) level of the territory, but the higher-level 'struct' map is cognitively useful.