在错误时跳转到标签的宏失败:使用未声明的标签

时间:2014-01-05 04:36:27

标签: c macros goto

我正在浏览Zed Shaw's tutorial on C debug macros,并且正在运行未声明的标签问题,请调用以下文件debug_macro.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define clean_errno() (errno == 0 ? "None" : strerror(errno))

#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)

#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }

int test_check(char *file_name)
{
    FILE *input = NULL;
    char *block = NULL;

    block = malloc(100);

    input = fopen(file_name, "r");
    check(input, "Failed to open %s.", file_name);

    free(block);
    fclose(input);
    return 0;

error:
    if(input) free(input);
    if(block) free(block);
    return -1;
}


int main(int argc, char *argv[])
{
    // open up a bogus file and then trigger error
    check(test_check("bogus.txt") == 0, "failed with bogus.txt");
    return 0;
}

当我用ccgcc编译它时,我收到以下错误:

gcc -Wall -g -O0 -I/opt/X11/include   goto.c   -o goto
goto.c:36:5: error: use of undeclared label 'error'
    check(test_check("bogus.txt") == 0, "failed with bogus.txt");
    ^
goto.c:10:78: note: expanded from macro 'check'
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
                                                                             ^
1 error generated.
make: *** [goto] Error 1

shell returned 2

Press ENTER or type command to continue

扩展宏时,会在goto error函数中插入test_check,其中定义了error:标签,所以我不知道为什么我会得到这个编译器错误。

1 个答案:

答案 0 :(得分:3)

您正试图从main跳转到另一个函数test_check,但goto只能跳转到同一函数内的标签。

  

C11§6.8.6.1goto陈述

     

goto语句导致无条件跳转到以named为前缀的语句   封闭功能中的标签。