lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Marco Salamone once stated:
> Sorry for the quick follow-up, I just had one more question for Tim.
> 
> >However, *no* language will do the kind of thing you are proposing, since
> the language must map to the underlying CPU architecture, and in general
> these are designed to work optimally on numeric values of certain sizes
> (for example, 32 or 64 bit integers).
> 
> In C, if I have a pointer to an integer that stores 20 and then I assign a
> new pointer the value of the original pointer+2-bits (bit-shift by 2),
> wouldn't my new pointer be pointing to the 4? I haven't played with
> anything like that in C before so I'm not exactly sure if you can get away
> with that or not, but this shouldn't any different, in principle, from how
> shifting a pointer along an array works. Obviously I'm missing something
> here.

  C doesn't work that way.  In fact, I don't know of any CPU architecture
that works that way.  The smallest addressable unit on computers is the
byte, an 8-bit quantity.  There is no way of addressing any smaller unit
than that.  Yes, you can work with individual bits, but it involves
manipulating at least 8 bits to isolate the single bit you want (or
bits).  Of course, you can specify the size of integral types in bits, but
there are restrictions---it *has* to be in a struct definition and you may
have unused bits.  For stance:

	struct foo
	{
	  int x : 5;
	  int y;
	  int z : 1;
	};

  on a typical 32-bit C compiler, this will be laid out in memory as:

	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|    x    |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|                             y                                 |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|z|
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

You might think that a ton of bits are wasted, but that's the nature of C. 
C guarentees that the fields will appear in the order given.  A lot of CPUs
can't reference 32-bit quantities on odd addresses (or even on addresses not
divisible by 4).  So padding is a given.  Re-arrange the structure:

	struct foo
	{
	  int x : 5;
	  int z : 1;
	  int y;
	};

And you might end up with:

	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|    x    |z|
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|                             y                                 |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

(there's also a caveat:  a signed one-bit quantity technically can contain 0
and -1---be careful!)

  Now, going back to your question about pointers---they don't work like you
think they work.  Again, in C, the following (again, assuming a 32-bit
system):

	int  x = 20;	/* x is 20 */
	int *p = &x;	/* p points to x */

	p = p + 2;

  p now points to memory 8 bytes away from x.  Not 2 bits.  *8 bytes* (two
integers worth of memory).  

  Can you address individual bits?  Yes ... but at a cost.  A cost that most
people aren't willing to pay actually.

  -spc (But I'm afraid I'm straying too far from Lua ... )