This is something that's been bothering me since I've learned C. Take the following code:<p><pre><code> *(int*)pointer_param = bar;
</code></pre>
In the above code the two * operators do two different things:<p>1. Converts variable type to pointer.<p>2. References value found at address.<p>What was the historical reason for using the * operator for both things? Memory? Is it easier to write a compiler for? Is there something I'm missing?<p>EDIT:Code, also, It seems like a lisp version would be much easier to write a compiler for and to write; i.e.<p>(define (address-ref (float_pointer_cast pointer_param))
bar)<p>Is there some reason that the C-version is easier to write a compiler for/optimize than the lisp?
I imagine the rationale was something like: how do we indicate that types are references to memory? Let's be concise and use the asterisk after the type of the memory.<p>How do we dereference an address? Since it only makes sense that types with an asterisk will be dereferenced, let's use an asterisk like we did in the type declaration. There, we have uniformity.<p>Oh wait, f-. What about if we want the address of something on the stack? Oh, maybe use the ampersand, and then that returns a pointer just like a pointer to something on the heap. Awesome! Let's even extend that ampersand to return the address of anything. Dereferenced pointers. What have you.<p>And yet, it's not completely symmetrical. Hence, pointers not being completely intuitive.<p>In addition, the ampersand as 'reference' is another completely unrelated syntax convenience. Which of course makes the language even slightly less symmetrical.<p>But, once you understand exactly what it's doing -- and your mind will adapt until it seems completely intuitive -- it is quite concise.<p>But the trick is that it's not concise like s-expressions. There's no clear symmetry. A lot of C (and even more C++) is simply syntax.
The second * has nothing to do with type-casting -- it is part of the type identification. The operator performing the typecast is the pair of parentheses.<p>Consider: int and int * are two different types. So typecasting to int when you really mean int * is completely different.
The * in the parentheses is part of type name and it indicates that the type being named is the sort of type to which it makes sense to apply the run-time * operator.
Substitute the obvious character for $%^& below -- I couldn't figure out how to convince HN that I wasn't just delimiting italics.<p><i>What was the historical reason for using the $%^& operator for both things?</i><p>I think the argument was that it allows you to say "foo is a pointer to an integer" == (int $%^&) foo == int ($%^& foo) == "that which is pointed to by foo, is an integer".
(Mentally replace all ^s with asterisks in the following:)<p>I don't understand your C code. What is "(int foo^)" supposed to do? It looks almost like a cast, but "int foo" isn't a valid type in C. Maybe "(struct foo^)" or "(int^)"?