C-type-gen [long] (help with a MESSY C definition)
Dave Jones
djones at megatest.UUCP
Sat Nov 19 09:10:41 AEST 1988
>From article <207600008 at s.cs.uiuc.edu>, by dlee at s.cs.uiuc.edu:
>
> I usually don't have any trouble with C, but this is a
> glaring exception: I need the syntax of definition for an array
> (of arbitrary size) of pointers to functions returning pointers to
> integer (HOW'S *THAT* FOR A DOOZY!!!).
As doozies go, it is a very excellent doozy indeed. You should
be very proud.
>
> My closest (possibly correct) guess follows:
>
> int *(*opfuncs[])() = {
> .
> .
> .
> };
>
You win, Mr. Presky! Come back next week to try for the Grand
Prize: A week's supply of designer roofing nails and an all expense-
paid vacation for none to Holland, where you can stick your finger
in a dike!
I've got a little program to figure these things out. There is
also a more involved program called "cdecl" which I have seen posted
to the net a couple of times, but I don't know anything about it.
I don't remember if I have posted this to an archive. Most of
the moderators are not interested in programs this short.
So I'll just include it here...
#include <stdio.h>
#include <setjmp.h>
/*
** I got tired of straining my fragile synapses writing C type-declarators.
** So I wrote this little program.
**
** You enter a declaration for the type using prefix notation.
** The implicit base-type is always "int", (why not), and the
** implicit type-name is "foo", (of course).
**
** '^' means "pointer to"
**
** '_' means "array of"
**
** '!' means "function returning"
**
** So for example, if you want a declarator for an array of pointers to
** functions returning int, you say,
**
** _^!
**
** and it says
**
** int (*foo[])();
**
*/
/*
** In C, () and [] are postfix, left-associative operators, and have
** a high precedence.
**
** * is a prefix, right-associative operator, and has a low precedence.
*/
#define LEN 256
static char decl[LEN];
jmp_buf restart;
main()
{
int ch;
printf("\n_ array of\n^ pointer to\n! function returning\n\n");
setjmp(restart);
do
{
int i = 0;
printf("? "); fflush(stdout);
do
{
if(i >= LEN ){ fprintf(stderr, "Too long. So long.\n"); exit(1); }
ch = getchar();
if(ch != EOF) decl[i++] = ch;
}
while(ch != '\n' && ch != EOF);
if(ch != EOF) print_type_def();
}
while(ch != EOF);
exit(0);
}
print_type_def()
{
print_left(0);
printf("foo");
print_right(0);
printf(";\n");
}
print_right(i)
int i;
{
switch(decl[i])
{
default:
printf("\Hold it! What's a '%c'?\n", decl[i]);
longjmp(restart);
case '\n':
return;
case '^':
if( decl[i+1] == '_' || decl[i+1] == '!')
putchar(')');
break;
case '_':
printf("[]");
break;
case '!':
printf("()");
break;
}
print_right(i+1);
}
print_left(i)
int i;
{
switch(decl[i])
{
default:
printf("\Hold it! What's a '%c'?\n", decl[i]);
longjmp(restart);
case '\n':
printf("int ");
return;
case '^':
print_left(i+1);
if( decl[i+1] == '_' || decl[i+1] == '!')
putchar('(');
putchar('*');
break;
case '_':
case '!':
print_left(i+1);
break;
}
}
More information about the Comp.lang.c
mailing list