[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
contains:
/* 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.
- implicit declaration of function 'yylex' is invalid in C99, Ryan Schmidt, 2022/01/14
- Re: implicit declaration of function 'yylex' is invalid in C99, Akim Demaille, 2022/01/15
- Re: implicit declaration of function 'yylex' is invalid in C99, Ryan Schmidt, 2022/01/15
- Re: implicit declaration of function 'yylex' is invalid in C99, Akim Demaille, 2022/01/15
- Re: implicit declaration of function 'yylex' is invalid in C99, Paul Eggert, 2022/01/15
- Re: implicit declaration of function 'yylex' is invalid in C99, Ryan Schmidt, 2022/01/17
- Re: implicit declaration of function 'yylex' is invalid in C99, Paul Eggert, 2022/01/17
- Re: implicit declaration of function 'yylex' is invalid in C99,
Ryan Schmidt <=
- Re: implicit declaration of function 'yylex' is invalid in C99, Paul Eggert, 2022/01/20
- Re: implicit declaration of function 'yylex' is invalid in C99, Ryan Schmidt, 2022/01/20
- Re: implicit declaration of function 'yylex' is invalid in C99, Paul Eggert, 2022/01/20