0

My question is regarding statement expressions, which are added as an extension in GNU C. Consider the following code:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    int i = 0;
    printf("%d\n", i);

    {int i = 1;printf("%d\n", i);}

    printf("%d\n", i);
    return EXIT_SUCCESS;
}

Compiling (gcc -Wall -std=gnu99 lala.c -o lala) and running will yield:

0
1
0

This practice (usage of the extension) is fairly commonplace, notably in container_of in the Linux kernel:

#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                (type *)( (char *)__mptr - offsetof(type,member) );})

Similar to this case, I want to define a macro which declares a local variable and does something with it. However, I want to do so without polluting the variable names available at the current scope and avoid possible redefinitions. I was not able to find in the documentation information on how exactly the scoping happens in cases of redefinitions.

In the case above, no warning is issued from the compiler regarding a redefinition. My question is whether I can rely on the fact that the variable scoped inside the statement expression will not affect the variable of the same name in the outer scope?

Charles
  • 50,943
  • 13
  • 104
  • 142
Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
  • What's not allowed is declaring variables whose names begin with two underscores. – dreamlax Apr 27 '12 at 12:50
  • 2
    Isn't your usage just a compound statement? for it to be a statement expression it would have to be enclosed in parenthesis according to the linked documentation – msam Apr 27 '12 at 12:55
  • @msam: yes, but I want to define a macro using the parenthesis – Mike Kwan Apr 27 '12 at 12:58

2 Answers2

2

Sure this is safe, this is what scopes are made for.

(And as dreamlax indicates in his comment, identifiers with two underscores are reserved for the implementation (compiler, library, hosting environement...) so you shouldn't use them.)

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Right, silly question :P The keyword that I should've known was 'shadow variable', something I have surprisingly not come across before (probably because in general people avoid them). – Mike Kwan Apr 27 '12 at 13:14
0

Regarding scope

from 3.1.2.1 ANSI C (similarly 6.2.1 in C99):

If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the } that closes the associated block

...

If an outer declaration of a lexically identical identifier exists in the same name space, it is hidden until the current scope terminates, after which it again becomes visible.

So assuming the compiler is compliant you should be able to make your assumption that the variable scoped inside the expression will not effect the variable in the outer scope

msam
  • 4,259
  • 3
  • 19
  • 32