Re: [cc65] function pointer, fastcall

From: Greg King <greg.king41verizon.net>
Date: 2008-08-30 08:27:24
From: "Ullrich von Bassewitz"; on Thursday, August 28, 2008; 04:59 PM -0400
>
> While "far" and "near" are part of a type, and also can be applied to any
> object, "fastcall" can be applied to only functions or function-types,
> but not to pointers.  A pointer may point to a fastcall function; but, it
> is itself not "fastcall".
>
> Because of syntax requirements, those modifiers modify the object or
> pointer to their right.  So,
>
>     void fastcall Func(int);
>
> defines a fastcall-function, while
>
>     void (* fastcall Func) (int);
>
> defines a pointer-to-a-fastcall-function (please note:  that is not
> the syntax currently required by cc65).  Using
>
>     void (fastcall * Func) (int);       /* illegal! */
>
> would be illegal, because on the right of the "fastcall" modifier is
> a pointer, and a pointer cannot be fastcall.
>
>     void fastcall far Func (int);
>
> is a fastcall-function that must be called by "far" addressing, while
>
>     void (* fastcall far Func) (int);
>
> is a pointer-to-a-fastcall-function that must be called using "far"
> addressing.  That implies that the pointer itself is also "far".  Using
>
>     void (far * fastcall far Func) (int);
>
> says the same, but explicitly:  The pointer also is declared "far".
>
>     void (near * fastcall far Func) (int);
>
> means a near-pointer-to-a-far-function.  That may or may not be useful or
> allowed.

But, those parentheses are how the C language names "function objects!"
Therefore, the proper syntax must be:

    void fastcall ()(int);

The entire "()(int)" is the object that sits to the right of the qualifiers;
"()" is the name of the function -- it doesn't matter whether or not there
is a "*" inside of that name.

    void fastcall (*)(int);

means:  a pointer to an object -- the object is a function -- the object
is a fastcalled function -- the object doesn't return any data.

As far as a compiler is concerned, the "token" that is being qualified by
"fastcall" is "(", not "*".  The compiler must "balance" that parenthesis;
and then, it must "look ahead," see that a left-parenthesis follows
_immediately_, and realize that it is parsing a function-object.
The "pointer to an <unspecified thing>" part would have been handled
-- separately -- during the balancing.  The two parts would be joined
together after the function-qualifiers had been "attached"
to the function-object.

Another thing that you should consider is that the pointer is the object
at the base of that declaration.  The function actually is a modifier
of that pointer!!  The "(" (with its tail) modifies the "*" -- their
positions are just as you stated.

Therefore, this is where the address keywords should go:

    void fastcall far (near *)(int);

means a near-pointer-to-an-object-that's-a-fastcalled-far-function.  And,

    void fastcall near (far *)(int);

means a far-pointer-to-an-object-that's-a-fastcalled-nearby-function.

Let's try a "real-looking" example:

extern char * fastcall avalanche(int mountain);
static char * fastcall near (far *snow)(int)
    = (char * near fastcall (far *)(int))avalanche;
....
....
....
    printf("%s\n", snow(K2));
....
....

----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sat Aug 30 08:28:52 2008

This archive was generated by hypermail 2.1.8 : 2008-08-30 08:28:54 CEST