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 Patrick once stated:
> Hi Adam
> 
> Thanks for answering my post :)
> 
> Just so I get this straight....
> 
> If we create a pointer:
> 
> int * foo
> 
> no memory has been taken but when foo is assigned a value it is:
> foo = 2 ;
> foo can be passed to functions but the value it points to is not, foo is 
> passed by reference.

  Not quite.  Take the following declarations:

	int foo;
	int *pfoo;

  Assuming a 32-bit implementation [1], the compiler will create the
following memory layout:

			+--------+--------+--------+--------+
	0x12345678	|        |        |        |        |	foo
			+--------+--------+--------+--------+
	0x1234567C	|        |        |        |        |	pfoo
			+--------+--------+--------+--------+

  The address 0x12345678 (made up for this example) is labled 'foo' and will
store a 32-bit integer.  The address 0x1234567C (again, made up) is labeled
'pfoo' and will store the address of an integer (and on a 32-bit
implementation, is 32 bits as well).  As of right now, the contents are
undefined [3], but given the following (assuming these lines appear within a
function somewhere):

	foo = 5;
	pfoo = &foo;

the contents of the memory locations are (ignoring byte ording issues as
that's beyond the scope of this reply):

			+--------+--------+--------+--------+
	0x12345678	|                 5                 |	foo
			+--------+--------+--------+--------+
	0x1234567C	|             0x12345678            |	pfoo
			+--------+--------+--------+--------+

'pfoo' is a four-byte quantity who's contents are to be treated as an
address to an integer.  'foo' is a four-byte quantity who's contents are to
be treated as an integer.  Both take memory to store, but what they store is
different [5].

  When you call a function with pfoo:

	bar(pfoo);

  you are passing the value of pfoo (in this case, 0x12345678) to function
bar().  A call like:

	baz(*pfoo);

  will read the contents of pfoo (0x12345678), then read the contents of the
given address (5) and pass that on to baz().  	

> The type of pointer will tell the compiler how many bytes to reserve in 
> the address space during assignment.

  The type of pointer tells the compiler how to interpret the memory pointed
to by the pointer.  It also tells the compiler how many bytes to reserve for
the pointer itself [6].

> If we do the same with lua_State * foo
> 
> Is it again just a matter of bytes and that the actual types that the 
> memory will hold are not vitally important, only that enough have been 
> reserved for what will be assigned to the location?
> 
> I get a warning with this but it compiles
> 
> int main(void)
> {
> lua_State *L;
> L = 1 ;
> return 0;
> }

  In that case, you have a pointer being assigned an integer value, which
the C compiler warns against, because semantically it doesn't mean anything. 
Even something like:

	int main(void)
	{
	  int *foo;
	  lua_State *L;

	  L = &foo;
	  return 0;
	}

will produce an error, because even though you are assigning the address of
something to L, which is a pointer, the address being used is of the wrong
type ("address to int" instead of "address to lua_State").  And a lua_State
is more than just an integer, it's a struct.  And it's at this point, if you
have to ask "What is a struct?" that I might recommend picking up a book or
two on C programming.  A good one (if a bit terse) is _The C Programming
Language_ by Kerninghan and Ritchie [8].

  -spc (Pointers tend to be one of the harder aspects of C for beginners to
	understand)

[1]	A 64-bit implemetation works simularly, except the resulting sizes
	are twice the size of a 32-bit implementataion.  A 16-bit
	implementation [2] will result in using half the memory of a 32-bit
	implementation.

[2]	For an example of this, you pretty much have to go back to the
	mid-80s and C compilers for MS-DOS.

[3]	Not techncially.  Global variables are typically initialized to a
	bit pattern of 0 [4]; local variables (those declared inside of a
	function) are not initialized and really *are* undefined as to the
	contents (typically, some remnents of previous function calls;
	again, describing the call stack is beyond the point of this reply).

[4]	Which might not be a legally defined pointer or floating point
	value, but that's going beyond the scope of this reply.

[5]	Semantically.  At the CPU level, it's just two four-byte quantities
	that can be really anything---a pointer, an integer, a floating
	point number or a very short string.  It's the type declarations in
	C that help the compiler produce code that handles the quantities in
	an appropriate manner.

[6]	Per the C standard, not all pointers need be the same size.  A
	pointer to a char * can be different from one to an int *. 
	Extensions can even make two pointers to the same type be different
	sizes [7].

[7]	Again, going back to MS-DOS, there are compiler extentions that let
	you declare pointers as two byte values or four byte values, such
	that:

		__near int *p;
		__far  int *p;

	are different and can't necessarily be assigned from one to the
	other.

[8]	One of only two C books I own.  The other being _The Standard C
	Library_ by Plauger.