ARTAGE
ARTAGE

Reputation: 381

Declare variable in if statement (ANSI C)

Is there any way to declare variable in if statement (using ANSI C only) ?

Example:

if(int variable = some_function())
{
    return 1;
}

Upvotes: 6

Views: 17195

Answers (2)

axiqia
axiqia

Reputation: 332

From GCC extension:

A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression. Recall that a compound statement is a sequence of statements surrounded by braces; in this construct, parentheses go around the braces. For example:

({ int y = foo (); int z;
   if (y > 0) z = y;
   else z = - y;
   z; })

is a valid (though slightly more complex than necessary) expression for the absolute value of foo ().

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.)...

Simplified examples:

#include <stdio.h>
    
int main()
{
    if (({int a = 1; a;}))
        printf("Hello World: TRUE");
    else
        printf("Hello World: FALSE");

    return 0;
}

// output:
// Hello World: TRUE

#include <stdio.h>

int main()
{
    if (({int a = 0; a;}))
        printf("Hello World: TRUE");
    else
        printf("Hello World: FALSE");

    return 0;
}
// output:
// Hello World: FALSE

Does anyone really use it this way? Yes! As far as I know, Linux kernel simplifies code by means of this extension.

/* SPDX-License-Identifier: GPL-2.0-only */
#define __get_user(x, ptr)                      \
({                                  \
    int __gu_err = 0;                       \
    __get_user_error((x), (ptr), __gu_err);             \
    __gu_err;                           \
})

#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0)
#define unsafe_get_user(x,p,e) unsafe_op_wrap(__get_user(x,p),e)

https://elixir.bootlin.com/linux/latest/source/include/linux/uaccess.h#L365

Upvotes: 2

pmg
pmg

Reputation: 108938

No, you cannot do that.

What you can do is create a compound statement (anonymous or hanging block) just for the if

    {
        int variable;
        variable = some_function();
        if (variable) return 1;
    }
    /* variable is out of scope here */

Note that for this simple case you can call the function as the condition of the if (no need for an extra variable)

if (some_function()) return 1;

Upvotes: 10

Related Questions