bobg+@andrew.cmu.edu (Robert Steven Glickstein) (07/05/89)
You may recall that, a while ago, I asked the net about the demand that would exist for a C-program filter which could take the output of Yacc or Lex and make all global "yy" variables and functions "static". There was a large demand, and I have now written such a program. This program does not presently work, and its failure has to do with a deficiency in the C language. Perhaps one of you bright C wizards out there can help...? The original objective for "yyhide": Change the storage class of all defined identifiers in C source whose names begin with "yy" or "YY" to static. So for example, int yyfoo, *yybar; becomes static int yyfoo, *yybar; This didn't work because of the possible degenerate case int yyfoo, bar; so yyhide was changed to do this: static int yyfoo; int bar; This also didn't work because of this case: struct foo { int a, b; } yyfoo, yybar; which became static struct foo { int a, b; } yyfoo; static struct foo { int a, b; } yybar; (struct foo redefined). So yyhide's solution was to do this: struct foo { int a, b; }; static struct foo yyfoo; static struct foo yybar; So far, so good. The next problem was this case: extern int yyfoo; /* Arbitrary amount of code */ int yyfoo; which became extern int yyfoo; /* Arbitrary amount of code */ static int yyfoo; (yyfoo redefined). So yyhide did this: /* Arbitrary amount of code */ static int yyfoo; This was fine when yyfoo was an int, but when yyhide changed this extern struct foo yyfoo; /* Arbitrary amount of code */ struct foo yyfoo; to this /* Arbitrary amount of code */ static struct foo yyfoo; and something in the /* Arbitrary amount of code */ referred to yyfoo, the result was "yyfoo undefined". The provisional solution to this (and the current state of yyhide) was to change extern SomeRandomType yyfoo; /* Arbitrary amount of code */ SomeRandomType yyfoo; to static SomeRandomType yyfoo; /* Arbitrary amount of code */ But even this doesn't work because of this case: extern int *yyfoo; /* Arbitrary amount of code */ int yybar[] = {1, 2, 3}; /* Arbitrary amount of code */ int *yyfoo = yybar; which becomes static int *yyfoo = yybar; /* Arbitrary amount of code */ static int yybar[] = {1, 2, 3}; /* Arbitrary amount of code */ (yybar undefined [in definition of yyfoo]). The next step in the development of yyhide seems to be to do a dependency sort on the variable declarations, but that seems needlessly complicated. The problem, in effect, is that the Yacc and Lex templates both use "extern" declarations as a forward-declaration device, and that this hack does not work when the forwardly declared variable winds up being static. "Extern" is being overloaded in this sense, and it's kludgy, but there you have it. There seems to be no way to make a forward declaration for a static variable. If that's true, then does anyone have any good ideas? If that's false (you can forwardly declare a static variable in C), how is it done? Bob Glickstein