[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: implicit declaration of function 'yylex' is invalid in C99

From: Ryan Schmidt
Subject: Re: implicit declaration of function 'yylex' is invalid in C99
Date: Thu, 20 Jan 2022 10:51:51 -0600

On Jan 17, 2022, at 12:15, Paul Eggert wrote:

> On 1/17/22 02:07, Ryan Schmidt wrote:
>> How can I know whether these prototypes are the right ones or if they need 
>> to be different?
> You look at the implementation of yylex and yyerror,

I would love to but I don't know where they are. For grok, I see its yyerror 
implementation in the prologue of conf.y and I don't think yyerror is the cause 
of any problems for grok yet, but I don't see an implementation of yylex. That 
is and has always been the reason why this error has been difficult for me to 
know how to solve, in all of the software where I've observed it. Now that I 
know per the preceding messages in this thread what the default yylex prototype 
is I can insert that see if it fixes the problem, but for grok which does not 
appear to use the default yylex prototype, I need to use whatever its different 
prototype is, and I don't know how to determine that.

> and make sure the prototype declarations match the implementation's 
> definition. Best practice is for the implementation to use the declarations, 
> e.g. via '#include "y.tab.h"'.
>> Does a successful compile mean the prototypes were sufficiently correct?
> If you follow best practice, yes. If not, not.

In what way might code that does not follow this best practice but which still 
compiles give the wrong result at runtime?

>> What about the static part? How would I have known that getdate.y needed the 
>> prototypes to be marked static? Or is that not needed there?
> 'static' means the functions are not visible outside the module defining 
> them. This is often useful (though not required) when the functions are 
> defined by the .y file and used only there.

I had read that "static" in the prototype and in the implementation is fine and 
gives you a static function; "static" in the prototype but not in the 
implementation is fine and gives you a static function; but that no "static" in 
the prototype but "static" in the implementation is an error. Therefore I was 
wondering how to know whether the implementation, wherever it is, is static. I 
guess the answer is that I will not use "static" unless I get an error message 
when not doing so.

>> What about the "int" return value of yyerror in getdate.y? Is that just a 
>> mistake and it should really be "void"?
> Yes, pretty much. This is explained in the Bison manual.

I'm sure the manual is great for those wanting to write programs using bison, 
but a manual is a difficult kind of document for someone who is almost 
completely unfamiliar with bison and who is just looking for an answer to a 
specific problem. I don't want to learn bison; I "just" want to fix other 
people's software--that worked fine with bison the last time its developers 
touched it years ago--so that it works again.

>> conf.tab.c:1302:1: error: conflicting types for 'yyparse'
>> yyparse (struct config *conf)
>> ^
>> conf.tab.h:116:5: note: previous declaration is here
> This is because grok's #include order is messed up. conf.y includes 
> conf.tab.h (which uses the type struct config) before it includes 
> grok_config.h (which defines the type). C requires declaration before use, so 
> it should include the files in the other order. Some compilers will go ahead 
> and compile anyway, depending on their flags; others won't.

I see conf.lex has the same incorrect include order. I can certainly change it 
in both places and propose that to the developer of grok, unless you would like 
to do so.

>> conf.tab.c:1495:23: error: too many arguments to function call, expected 0, 
>> have 2
>>       yychar = yylex (&yylval, &yylloc);
> This is because the yylex declaration is missing. Add 'int yylex (YYSTYPE 
> *);',

How did you know to do that? Just by looking at conf.yy.c? I see that it 

/* Default declaration of generated scanner - a define so the user can
 * easily add parameters.
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1

extern int yylex \
               (YYSTYPE * yylval_param );

#define YY_DECL int yylex \
               (YYSTYPE * yylval_param )
#endif /* !YY_DECL */

But this is a generated file. If I run "make reallyreallyclean" it disappears, 
and is regenerated by "make" through "flex -o conf.yy.c conf.lex". What 
information in conf.lex leads to this function prototype being generated?

When I use your proposed prototype, I still get the error:

conf.tab.c:1496:32: error: too many arguments to function call, expected 1, 
have 2
      yychar = yylex (&yylval, &yylloc);
               ~~~~~           ^~~~~~~
conf.y:15:1: note: 'yylex' declared here
int yylex (YYSTYPE *);
1 error generated.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]