【问题标题】:Implicit declaration/conflicting types for 'warning' while compiling a basic sample (hoc1) yacc program编译基本示例 (hoc1) yacc 程序时“警告”的隐式声明/冲突类型
【发布时间】:2020-10-25 08:49:49
【问题描述】:

我正在关注经典的 Kernighan & Pike Unix 编程环境;特别是涵盖 yacc 的章节。 在第一个示例中,使用 yacc 准备了一个名为 hoc1 的基本计算器。

按照本书我准备以下代码:

%{
#define YYSTYPE double
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
list:
    | list '\n'
    | list expr '\n'    { printf("\t%.8g\n", $2); }
    ;
expr:     NUMBER        { $$ = $1; }
    | expr '+' expr     { $$ = $1 + $3; }
    | expr '-' expr     { $$ = $1 - $3; }
    | expr '*' expr     { $$ = $1 * $3; }
    | expr '/' expr     { $$ = $1 / $3; }
    | '(' expr ')'      { $$ = $2; }
    ;
%%

#include <stdio.h>
#include <ctype.h>
char    *progname;
int lineno = 1;

int main(int argc, char *argv[]) {

    progname = argv[0];
    yyparse();
    
}


int yylex(void) {

    int c;
    
    /* Left trim all spaces/tabs */
    while((c=getchar()) == ' ' || c == '\t');
    
    /* Return 0 if EOF */
    if(c== EOF) {
        return 0;
    }
    
    /* Return NUMBER if number */
    if(c=='.' || isdigit(c)) {
        ungetc(c,stdin);
        scanf("%lf", &yylval);
        return NUMBER;
    }
    
    /* Count lines */
    if(c=='\n') {
        lineno++;
    }
    
    return c;       
    
}

void yyerror(char *s) {
    
    warning(s, (char *)0);

}

void warning(char *s, char *t) {

    fprintf(stderr, "%s: %s", progname, s);
    if(t) {
        fprintf(stderr, " %s", t);
    }
    fprintf(stderr, " near line %d\n", lineno);

}

但我在编译程序时遇到以下错误:

~/tutorials/unix_programming_environment/hoc1 % yacc hoc1.y

~/tutorials/unix_programming_environment/hoc1 % cc y.tab.c -o hoc1

hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]
        warning(s, (char *)0);
        ^
hoc1.y:68:6: error: conflicting types for 'warning'
void warning(char *s, char *t) {
     ^
hoc1.y:64:2: note: previous implicit declaration is here
        warning(s, (char *)0);
        ^
1 warning and 1 error generated.

我既不理解警告也不理解错误。

编辑:在 FreeBSD 12.1 中使用 yacc

【问题讨论】:

  • @zwol:为什么你认为问题是yacc 中的一个错误,而不是他们在使用之前没有声明warning
  • 请记住,这本书出版于 1984 年,早在标准 C 出现之前。当时也没有可靠的 void 类型。也没有&lt;stdlib.h&gt;
  • @EricPostpischil 哎呀。我没有注意到滚动条,所以我认为错误代码来自解析器框架。
  • 其实这本书使用的是K&R风格(我没用过)。因此,我尝试将示例改编为 ANSI C89。

标签: c freebsd yacc c89 ansi-c


【解决方案1】:

yyerror函数的定义移到warning函数的定义之后或将此行放在yyerror函数之前:

void warning(char *, char *);

此编译器消息:

hoc1.y:64:2:警告:函数“警告”的隐式声明在 C99 中无效 [-Wimplicit-function-declaration]

告诉你函数warning 在看到它的任何声明之前就被使用了。由于 C 语言的历史,这会导致隐式声明。

此编译器消息:

hoc1.y:68:6:错误:“警告”的类型冲突

告诉你warning 的实际定义与上面的隐式声明的类型不同。

对此的解决方案是在使用之前声明warning,您可以通过在使用之前放置定义(即声明)或在使用之前放置单独的声明来做到这一点。

【讨论】:

  • 感谢您的解释,它帮助我了解了实际发生的情况。
猜你喜欢
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 1970-01-01
相关资源
最近更新 更多