Marius Pop Marius Pop - 3 months ago 20
C Question

error: expected expression; use of undeclared identifier

I'm trying to learn c.

I have the following code in the main function:

switch (action) {
case 'c':

int max_data = atoi(argv[3]);
int max_rows = atoi(argv[4]);
Database_create(conn, max_data, max_rows);
Database_write(conn);


The compiler throws the following errors:

mydb.c:107:7: error: expected expression
int max_data = atoi(argv[3]);
^
mydb.c:110:29: error: use of undeclared identifier 'max_data'
Database_create(conn, max_data, max_rows);


However, if I call the printf function as you can see bellow I don't get any error at compile time.

switch (action) {
case 'c':
printf("HELLO");
int max_data = atoi(argv[3]);
int max_rows = atoi(argv[4]);

Database_create(conn, max_data, max_rows);
Database_write(conn);


Or if I just pass the arguments straight to the function I still don't get those errors:

switch (action) {
case 'c':
Database_create(conn, atoi(argv[3]), atoi(argv[4]));
Database_write(conn);


Any help in shedding some light on a novice on why this happens will be greatly appreciated!

Answer

A case label can only be applied to a statement, not to a declaration.

A case label can be followed by multiple statements (which will be executed in sequence), but the thing that immediately follows case 'c': must be a statement.

Adding braces will fix the problem:

switch (action) {
    case 'c': {
        int max_data = atoi(argv[3]);
        int max_rows = atoi(argv[4]);
        Database_create(conn, max_data, max_rows);
        Database_write(conn);
    }
    /* ... */
}

If your compiler supports C99 or later (which permits mixing declarations and statements), then you can also work around the problem by adding a null statement after the case label:

switch (action) {
    case 'c': ;
        int max_data = atoi(argv[3]);
        int max_rows = atoi(argv[4]);
        Database_create(conn, max_data, max_rows);
        Database_write(conn);
    /* ... */
}

but that's ugly and I don't recommend it. For one thing, adding braces means that the scope of the declarations is restricted to the single branch in which they appear; with the : ; hack, their scope extends to the end of the enclosing block.

(In C++, declarations are a subset of statements, so your code would be valid. This isn't directly relevant, since you asked about C -- and this isn't a good reason to switch languages.)

Comments