Declare variable in if statement (ANSI C)
Asked Answered
H

2

6

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

Example:

if(int variable = some_function())
{
    return 1;
}
Hagar answered 26/4, 2017 at 19:51 Comment(6)
No. That is not allowed in C.Yellows
#8474600Otolith
According to the ANSI C Grammar, the grammar for the if statement is IF '(' expression ')' statement. expression cannot resolve to declaration, so there is no way to put a declaration in an if statement like in your example.Forsyth
Declare a variable strictly using a classic declaration of format type var = value? No.Mehta
@RandomDavis That grammar is not up to date (but that particular production hasn't changed). Note that IF in that grammar refers to the if keyword (IF is an ordinary identifier). The grammar in the ISO C standard is if ( expression ) statement or if ( expression ) statement else statementAzriel
I never used to appreciate the value of this construct until I realized how repetitive code gets when you are checking an error flag.Upper
P
10

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;
Pennyroyal answered 26/4, 2017 at 19:55 Comment(2)
If you mean anonymous braces, I'm happy about that. I think they're underrated and are a great first step for refactoring.Upper
The Standard calls them "compound statements" (C11 6.8.2)Pennyroyal
Q
2

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

Quietism answered 16/6, 2022 at 1:48 Comment(1)
Interesting, though presumably you can't access the variable declared in the test expression from the 'then' statement.Terminable

© 2022 - 2024 — McMap. All rights reserved.