简体   繁体   中英

ISO C90 forbids mixed declarations and code sscanf

I'm getting a strange error attempting to compile my unit test code,. For some reason the compiler treats my sscanf call as a mixed declaration? I don't quite understand, here is the entire error:

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;
}

In C90, all declarations must come at the beginning of a block. Put this:

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

above these statements:

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

C90 requires all declarations to precede all statements within a block.

C99 (like C++) permits declarations and statements to be mixed.

You have an assignment statement:

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

followed by a declaration:

bn_complex_t com1,com2;

(It shouldn't be complaining about the sscanf calls; check the line number in the error message against your source file.)

You can either rearrange the code, or modify your Makefile so it invokes the compiler in C99 mode. You appear to be using gcc; use -std=c99 (or -std=gnu99 if you want GNU-specific extensions. (The details of how to do this depend on how your Makefile is written.)

Or you can replace the assignments with initializers (which don't count as statements).

Personally, I prefer to have each declaration on a single line. I'd change this:

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

to this:

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;

But if you prefer a more compact layout, you can write:

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;

You still need an initializer for each variable, even if you declare multiple variables on a single line.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM