ISO C90禁止混合声明和代码sscanf

时间:2012-12-14 22:44:08

标签: c

我在尝试编译单元测试代码时收到一个奇怪的错误。出于某种原因,编译器将我的sscanf调用视为混合声明?我不太明白,这是整个错误:

cc1: warnings being treated as errors
/home/brlcad/brlcad/src/libbn/tests/bn_complex.c: In function 'main':
/home/brlcad/brlcad/src/libbn/tests/bn_complex.c:53: error: ISO C90 forbids mixed declarations and code
make[2]: *** [src/libbn/tests/CMakeFiles/tester_bn_complex.dir/bn_complex.c.o] Error 1
make[1]: *** [src/libbn/tests/CMakeFiles/tester_bn_complex.dir/all] Error 2
make: *** [all] Error 2

int
main(int argc, char *argv[])
{
    double expRe1, expIm2, expSqRe1, expSqIm2;
    double actRe1, actIm2, actSqRe1, actSqIm2;
    actRe1 = actIm2 = actSqRe1 = actSqIm2 =
    expRe1 = expIm2 = expSqRe1 = expSqIm2 = 0.0;
    bn_complex_t com1,com2; //a struct that holds two doubles
    if(argc < 5)
        bu_exit(1, "ERROR: Invalid parameters[%s]\n", argv[0]);

    sscanf(argv[1], "%lf,%lf", &com1.re, &com1.im); /* Error is HERE */
    sscanf(argv[2], "%lf,%lf", &com2.re, &com2.im);
    sscanf(argv[3], "%lf,%lf", &expRe1, &expIm2);
    sscanf(argv[4], "%lf,%lf", &expSqRe1, &expSqIm2);

    test_div(com1, com2, &actRe1, &actIm2);
    test_sqrt(com1,com2, &actSqRe1, &actSqIm2);

    if((fabs(actRe1 - expRe1) < 0.00001) || (fabs(actIm2 - expIm2) < 0.00001)){
        printf("Division failed...\n");
        return 1;
    }
    if((fabs(actSqRe1 - expSqRe1) < 0.00001) || (fabs(actSqIm2 - expSqIm2) < 0.00001)){
        printf("Square roots failed...\n");
        return 1;
    }
    return 0;
}

3 个答案:

答案 0 :(得分:7)

在C90中,所有声明都必须在块的开头。把这个:

bn_complex_t com1,com2; //a struct that holds two doubles

以上这些陈述:

actRe1 = actIm2 = actSqRe1 = actSqIm2 =
expRe1 = expIm2 = expSqRe1 = expSqIm2 = 0.0;

答案 1 :(得分:3)

C90要求所有声明都在块中的所有语句之前。

C99(与C ++一样)允许混合声明和语句。

你有一份作业声明:

actRe1 = actIm2 = actSqRe1 = actSqIm2 =
expRe1 = expIm2 = expSqRe1 = expSqIm2 = 0.0;

接着是声明:

bn_complex_t com1,com2;

(不应该抱怨sscanf次来电;请根据您的源文件检查错误消息中的行号。)

您可以重新排列代码,也可以修改Makefile,以便在C99模式下调用编译器。你似乎在使用gcc;如果您需要特定于GNU的扩展,请使用-std=c99(或-std=gnu99。(有关如何执行此操作的详细信息取决于您Makefile的编写方式。)

您可以使用初始化程序(不计为语句)替换分配。

就个人而言,我更愿意将每个声明放在一行上。我改变了这个:

double expRe1, expIm2, expSqRe1, expSqIm2;
double actRe1, actIm2, actSqRe1, actSqIm2;
actRe1 = actIm2 = actSqRe1 = actSqIm2 =
expRe1 = expIm2 = expSqRe1 = expSqIm2 = 0.0;

到此:

double expRe1   = 0.0;
double expIm2   = 0.0;
double expSqRe1 = 0.0;
double expSqIm2 = 0.0;

double actRe1   = 0.0;
double actIm2   = 0.0;
double actSqRe1 = 0.0;
double actSqIm2 = 0.0;

但如果你更喜欢更紧凑的布局,你可以写:

double expRe1 = 0.0, expIm2 = 0.0, expSqRe1 = 0.0, expSqIm2 = 0.0;
double actRe1 = 0.0, actIm2 = 0.0, actSqRe1 = 0.0, actSqIm2 = 0.0;

即使您在一行上声明多个变量,您仍然需要为每个变量创建初始值设定项。

答案 2 :(得分:2)

我不确定为什么错误位于编译器的位置,但C90要求所有变量声明都在块的顶部,因此bn_complex_t是错误的。