#1029118 Possible typo in "#if !(defined(yylex) ..."

Package:
byacc
Source:
byacc
Description:
public domain Berkeley LALR Yacc parser generator
Submitter:
Bjarni Ingi Gislason
Date:
2023-01-18 02:00:05 UTC
Severity:
normal
#1029118#5
Date:
2023-01-18 00:45:50 UTC
From:
To:
Dear Maintainer,

   * What led up to the situation?

  Compiling groff

####

output.c:       putl_code(fp, "#if !(defined(yylex) || defined(YYSTATE))\n");

  "yylex" is a name of a function but "#... defined(...)" applies to
macros not functions(?).

####

  When compiling, a warning is issued:

  CXX      src/preproc/eqn/eqn-eqn.o
src/preproc/eqn/eqn.cpp:73:23: warning: redundant redeclaration of 'int
yylex()' in same scope [-Wredundant-decls]
   73 | # define YYLEX_DECL() yylex(void)
      |                       ^~~~~
src/preproc/eqn/eqn.cpp:78:5: note: in expansion of macro 'YYLEX_DECL'
   78 | int YYLEX_DECL();
      |     ^~~~~~~~~~
../src/preproc/eqn/eqn.ypp:31:5: note: previous declaration of 'int
yylex()'
   31 | int yylex(void);
      |     ^~~~~
  CXXLD    eqn

####

  When I change "yylex" to "YYLEX" in the "putl_code(...)" line there
is no warning.

#1029118#10
Date:
2023-01-18 01:50:19 UTC
From:
To:
(in a quick check, I compiled the version from 2022/12/28
on my Debian/oldstable without seeing this problem - but I see
the issue is compiler options).

That's intentional (not a bug).  It's done to allow changing the function
signature -- but not if there's already a macro to confuse things.

Here's more context:

	/* Parameters sent to lex. */
	#ifdef YYLEX_PARAM
	# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
	# define YYLEX yylex(YYLEX_PARAM)
	#else
	# define YYLEX_DECL() yylex(void)
	# define YYLEX yylex()
	#endif

	#if !(defined(yylex) || defined(YYSTATE))
	int YYLEX_DECL();
	#endif

Changing that YYSTATE to YYLEX will turn off the declaration.

YYSTATE is a lex symbol (#define'd), so it seemed a better choice than
the flex-specific FLEX_SCANNER symbol which Guy Harris used in the first
version of this ifdef.

The intent here is to not use the declaration if the lex/flex code is
inserted before that point (reducing redefinition problems).

yes - that's a problem.  There's been no universally-guaranteed prototype
for yylex, so applications add one.  (There was some update on the Austin
review a couple of years ago, but the recommendation from that would run
into the same problem -- and it introduced other problems).

For this case, I could add a third symbol, which would "only" be set by
the caller (not a lex/flex symbol that one might trip over).

#1029118#13
Date:
2023-01-18 01:50:19 UTC
From:
To:
(in a quick check, I compiled the version from 2022/12/28
on my Debian/oldstable without seeing this problem - but I see
the issue is compiler options).

That's intentional (not a bug).  It's done to allow changing the function
signature -- but not if there's already a macro to confuse things.

Here's more context:

	/* Parameters sent to lex. */
	#ifdef YYLEX_PARAM
	# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
	# define YYLEX yylex(YYLEX_PARAM)
	#else
	# define YYLEX_DECL() yylex(void)
	# define YYLEX yylex()
	#endif

	#if !(defined(yylex) || defined(YYSTATE))
	int YYLEX_DECL();
	#endif

Changing that YYSTATE to YYLEX will turn off the declaration.

YYSTATE is a lex symbol (#define'd), so it seemed a better choice than
the flex-specific FLEX_SCANNER symbol which Guy Harris used in the first
version of this ifdef.

The intent here is to not use the declaration if the lex/flex code is
inserted before that point (reducing redefinition problems).

yes - that's a problem.  There's been no universally-guaranteed prototype
for yylex, so applications add one.  (There was some update on the Austin
review a couple of years ago, but the recommendation from that would run
into the same problem -- and it introduced other problems).

For this case, I could add a third symbol, which would "only" be set by
the caller (not a lex/flex symbol that one might trip over).