J
Joel VanderWerf
Austin said:No, I don't think that's a valid comparison because a void* still
takes up space -- it's a location -- in C++. That is, I can
legitimately do:
void* a = &5;
void* b = &a;
Not quite legitimately... you didn't mean to take the address of a
literal int, did you?
Anyway, in ruby you can do:
a = [1,2,3]
b = "a"
eval b # ==> [1, 2, 3]
a = [4,5,6]
eval b # ==> [4, 5, 6]
The analogy between eval and dereferencing pointers doesn't go very far,
but this snippet does demonstrate one thing: there is some storage,
somewhere, associated with a in this context while the program is
running. Not associated with the _value_ of a (the array has its own
storage independent of a), but associated with the _variable_ itself.
Without this storage there would be no way to eval the string "a".
C/C++ doesn't have this kind of storage: there's no way to evaluate "a"
at run-time. The association between the string "a" and a certain memory
location has been compiled out, which is why the program uses the
numerical address of that location instead.
In ruby, the storage for a is in the binding for the scope of the
snippet above. You can think of the binding as something that has a
table whose entries have two fields: a variable name and a pointer to a
value (or an immediate value encoded in 4 bytes instead of a pointer).
That's a different kind of storage than heap storage, where the arrays
are. Ruby makes it harder to access the storage of a binding directly
(you have to use #eval, #binding, #local_variables), but it does take up
real space and have a location in memory.
Ruby doesn't have an operator to take the address of that location.
(Ruby doesn't have any operators for working with addresses, except for
#object_id, and this exception is just a quirk of the implementation.)
But it is a location nonetheless. You can run out of memory by
overpopulating a binding.