Declaring variables in the arguments to a function in C

zmccord picture zmccord · Feb 27, 2012 · Viewed 7.5k times · Source

I have a sort of bizarre wish; I don't know if any compiler or language extension out there allows this.

I want to be able to declare variables inside a function invocation, like this:

int test(int *out_p) {
    *out_p = 5;
    return 1;
}

int main()
{
    if (int ret = test(int &var)) { // int var declared inside function invocation
        fprintf(stderr, "var = %d\n", var); // var in scope here
    }
    return 0;
}

because then the scoping of var follows the scoping of ret. For another example (from a project I'm working on now), I have

cmd_s = readline();
int x, y, dX, dY, symA, symB;
if (sscanf(cmd_s, "placeDomino:%d %d atX:%d y:%d dX:%d dY:%d",
                           &symA, &symB, &x,  &y,   &dX,  &dY) == 6) {
    do_complicated_stuff(symA, symB, x, y, dX, dY);
} else if (sscanf(cmd_s, "placeAtX:%d y:%d dX:%d dY:%d", &x, &y, &dX, &dY) == 4) {
    do_stuff(x, y, dX, dY);
    /* symA, symB are in scope but uninitialized :-( so I can accidentally
     * use their values and the compiler will let me */
}

and I would prefer to write

cmd_s = readline();
if (sscanf(cmd_s, "placeDomino:%d %d atX:%d y:%d dX:%d dY:%d",
                    int &symA, int &symB, int &x, int &y, int &dX, int &dY) == 6) {
    do_complicated_stuff(symA, symB, x, y, dX, dY);
} else if (sscanf(cmd_s, "placeAtX:%d y:%d dX:%d dY:%d", int &x, int &y, int &dX, int &dY) == 4) {
    do_stuff(x, y, dX, dY);
    /* Now symA, symB are out of scope here and I can't
     * accidentally use their uninitialized values */
}

My question is, does any compiler support this? Does gcc support it if I rub it the right way? Is there a C or C++ (draft) spec that has this?

Edit: just realized that in my first code example, my declaration of int ret is also no good in C99; I guess I'm spoiled by for loops. I want that feature too; imagine

while(int condition = check_condition()) {
    switch(condition) {
        ...
    }
}

or something like that.

Answer

Jens Gustedt picture Jens Gustedt · Feb 27, 2012

Besides block scope declarations, in C99 there are basically two other ways to declare variables that are by definition restricted to the statement in which they occur:

  • Compound literals are of the form (type name){ initializers } and declare a local variable that lives in the current block. E.g for a function call you could use test(&(int){ 0 }).
  • for scope variables only have the scope of the for statement itself and the depending statement or block.

Your if expression with local variable you could do something weird like

for (bool cntrl = true; cntrl; cntrl = false)
   for (int ret = something; cntrl && test(&ret); cntrl = false) {
      // use ret inside here
   }

Be careful, such things quickly become unreadable. On the other hand, optimizers reduce such code quite efficiently to the essential and easily find out that test and the inner side of the for block are only evaluated once.