woodman@sumax.UUCP (David Woodman) (12/06/89)
I want to thank all the people who took time to reply to my question. Here is a summary of best answers to the current 'obfuscated code' query: The question: What does this typecast do? struct MYSTRUCT someVariable; someVariable = (*((struct MYSTRUCT *)(*)()_msg))(parameters,...); I received two answers as follows: /**********************************************************************/ From: uw-beaver!ames.arc.nasa.gov!atari!kbad (Ken Badertscher) Subject: Re: Obfuscated code When unraveling wierd and wonderful typecasts such as the above, it's often best to start in the _middle_ rather than the beginning, as you tried. The point of Cox's discussion in the book, if I recall correctly, is that C is powerful enough for OOP because of the flexibility of identifiers. What he does in this example, is warp the meaning of the identifier _msg, which starts out as a function returning id. He wants _msg to return a struct MYSTRUCT *, rather than an id, so he uses a function cast: (struct MYSTRUCT *)(*)() ^^^^^-- "pointer to function" type ^^^^^^^^^^^^^^^^^^^------- return type of function This means, "cast the following identifier to a pointer to a function returning struct MYSTRUCT *." The identifier being cast is _msg. So now he has turned _msg into a function pointer, and in order to invoke it, he must give it arguments: ((struct MYSTRUCT *)(*)()_msg)( parameters,...) Annnnd, since he's assigning the return value to a struct, he needs to dereference the pointer returned by this function: someVariable = (*((struct MYSTRUCT *)(*)()_msg))( parameters,...); Voila! Feel free to post this info back to comp.lang.c, if you desire. Regards, Ken Badertscher Atari Corp. System Software Engine /**********************************************************************/ X-Origin: The Portal System (TM) X-Possible-Reply-Path: Tim_N_Roberts@cup.portal.com X-Possible-Reply-Path: sun!portal!cup.portal.com!Tim_N_Roberts Detangling a type definition or a cast is a tough thing. You basically work from the inside out. (*((struct MYSTRUCT *)(*)() _msg)) ^^^^^^^^^^^^^^^^^^^^^^^^ This is the cast. Lets take it apart piece by piece. (struct MYSTRUCT *)(*)() ^^^ Cast to a pointer to... ^^ a function ... ^^^^^^^^^^^^^^^^^^^ returning a pointer to MYSTRUCT If you had that cast typedef-ed to "pfmy", you could rewrite the call as: (*(pfmy)_msg)(arguments) which makes a little more sense; the name "_msg" without any arguments is a "pointer to function". We are casting that to a "pointer to function returning MYSTRUCT". We then dereference that to come up with a "function returning MYSTRUCT" and pass it the appropriate arguments. Note that pre-ANSI compilers do not require (some do not allow!) the very first "*" in the original statement; they automatically dereference pointers-to-functions by calling the function. The Microsoft C Language Reference has an excellent discussion on constructing and deciphering type definitions and casts. TNR@cup.portal.com | I Survived The ...!sun!portal!cup.portal.com!tnr | Great Quake of '89. /**********************************************************************/ -- ------------------------------------------------------------------------ David Woodman MAIL: woodman%sumax.uucp@beaver.cs.washington.edu Seattle University #include <disclaimer.std>