summary of obfuscated code request
David Woodman
woodman at sumax.UUCP
Wed Dec 6 12:18:13 AEST 1989
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 at 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 at cup.portal.com | I Survived The
...!sun!portal!cup.portal.com!tnr | Great Quake of '89.
/**********************************************************************/
--
------------------------------------------------------------------------
David Woodman MAIL: woodman%sumax.uucp at beaver.cs.washington.edu
Seattle University #include <disclaimer.std>
More information about the Comp.lang.c
mailing list