7

I have a global variable and a local variable with the same names. Can I copy the local variable to the global variable (assign) without first assigning the value of the global variable to some temporary variable (using extern) and then assigning the temporary variable to the global variable? I need to do something like this:

#include<stdio.h>
int myVariable = 50;
void myFunction()
{
    int myVariable;
    myVariable /*global*/ = myVariable /*local*/;
}

Is there some way in C to do it (without using temporary variables (or pointers in case of arrays))? I found it's possible in C++, Java or C# using keywords like this, super, base, etc. but couldn't find a solution in C.

I have already referred to How can I access a shadowed global variable in C?

Community
  • 1
  • 1
Sachin Joseph
  • 18,928
  • 4
  • 42
  • 62
  • 8
    Yes, it's possible. Just don't use `myVariable` in local scope. – masoud Aug 14 '13 at 18:38
  • 4
    possible duplicate of [How can I access a shadowed global variable in C?](http://stackoverflow.com/questions/618769/how-can-i-access-a-shadowed-global-variable-in-c) – Macattack Aug 14 '13 at 18:39
  • If you can write code to perform the copy, is there something keeping you from local-replacing the local-variable name with something that doesn't conflict with the global name? – WhozCraig Aug 14 '13 at 18:40
  • 1
    Usually it's bad coding practice to do this. Especially in C where you can't do { this.x = x; } You should probably change one of the variable's names. – Isaac Aug 14 '13 at 18:42
  • 2
    @Macattack, not quite a duplicate. – Jacob Pollack Aug 14 '13 at 18:43
  • 1
    @Macattack I was not asking how to access a shadowed variable in C. I know it can be accessed using extern keyword. I've specified that in my question also :-) – Sachin Joseph Aug 14 '13 at 18:49
  • 2
    @SachinJoseph My apologies, I leaped before I looked. I do hope you are only asking for theoretical purposes. – Macattack Aug 14 '13 at 19:01
  • 2
    @SachinJoseph, I clarified your edits quoting the C99 standard. There is no equivalent of super, etc. in C. – Jacob Pollack Aug 14 '13 at 19:06
  • ...just use a different name and spend your time solving real problems. – Ed S. Aug 14 '13 at 19:54
  • 3
    @EdS., this is a credible problem. It's a feature directly supported in other languages. – Jacob Pollack Aug 14 '13 at 19:58
  • 1
    @JacobPollack: I fail to se how that is relevant, and it's not a "credible problem" as you can simply change the variable name and move on with your life. The question is specific to C and, in C, you can't distinguish between the two. What Java or any other language provides is neither here nor there. – Ed S. Aug 14 '13 at 20:39

7 Answers7

13

In C99 there is no way to specify the specific scope of the variable/constant you want to use. It will automatically refer to the inner-most scope when referring to a variable/constant.

From the C99 standard 6.2.1.4:

... If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a strict subset of the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope ...

So how would I get around this?

Simple, change the name of the inner-most scope variable :)

Jacob Pollack
  • 3,703
  • 1
  • 17
  • 39
6

This is horrible, but in GNU C, you can do it with:

* ({ extern int myVariable; &myVariable; }) = myVariable;

Come to think of it, that could serve in standard C with a helper function:

static int * GlobalMyVariable(void) { return &myVariable; }
…
*GlobalMyVariable() = myVariable;

Of course, you asked for no temporary variables, and this does not use a temporary variable, but it does, on the face of it, add “stuff” to your executable. However, I compiled a simple use of this with optimization, and the helper function vanished completely in the generated assembly code. So it amounts to no extra code or data, when the compiler optimizes properly.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
2

Does a struct count as another variable?

#include<stdio.h>

struct Global {
    int myVariable;
} g;

void myFunction()
{
    int myVariable = 50;
    g.myVariable /*global*/ = myVariable /*local*/;
}

That should do something like you ask about.

Shade
  • 775
  • 3
  • 16
  • 3
    (+1), because this is a clever work around. But, (-1) since it is implicitly not what the OP wanted to do -- if anything this is more work than making a temporary variable/constant. – Jacob Pollack Aug 14 '13 at 18:50
  • +1 A similar workaround I saw a couple of times is to start the name of every global variable with "g_". – kol Aug 14 '13 at 20:00
1

Add a global constant int pointer.

OP: How to copy local variable to global variable if both have the same array names in C without using a third variable?
I cheated and am not using a third variable but a constant. (did I sneak through the door?)

OP: without first assigning the value of the global variable to some temporary variable (using extern) and then assigning the temporary variable to the global variable?
Appears to pass that test - no temporary variable used.

OP: some way in C to do it (without using temporary variables (or pointers in case of arrays))?
Well it not using a temporary, as globals are permanent. And its not using a pointer via an array. It is using a pointer.

int myVariable = 50;
int *const myVariableAddress = &myVariable;

void myFunction() {
    // Could be here instead with 
    // static int *const myVariableAddress = &myVariable;
    {
    int myVariable;
    *myVariableAddress = myVariable /*local*/;
    }
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

This works, but the code needs to be in a shared object, or the program needs to be compiled in a way that lets the executable see its own global symbols (in GCC, you use the -rdynamic flag):

int myVariable = 50;

void myFunction () {
    int myVariable = 10;
    *(int *)dlsym(0, "myVariable") = myVariable;
}
jxh
  • 69,070
  • 8
  • 110
  • 193
-1

1) use the return value:

#include<stdio.h>
int myVariable = 50;

int myFunction1()
{
    int myVariable;
    return  myVariable;
}

2) use a pointer:

void myFunction2( int * pp)
{
    int myVariable;
    *pp = myVariable;
}

Usage:

int main(void) {

myVariable = myFunction1();

 /* or ... */
myFunction2 ( &myVariable);

return 0;
}

}

wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • (-1), I do not understand any of the examples. In the first one you will get an error saying "reached end of non-void function", the second one has no change but the parameter type and the usage is unclear since I do not know what the first two points do... – Jacob Pollack Aug 14 '13 at 18:56
  • I was still busy editing. (and understanding the question which does not make much sense to me) Both versions do not use any extra variable (the pointer could be seen as a variable, but the actual argument is a pointer expression, and this "variable" disappears once the function has returned.) – wildplasser 33 secs ago – wildplasser Aug 14 '13 at 18:57
-2

What you're doing is "shadowing" the global variable. In order to unshadow it in a local block, declare it in its own nested block with extern.

 void myFunction()
 {

  int myVariable
   {
     extern int myVarible; 
     //modify myVariable global here;

    }
   //modify myVariable localhere
 }
KrisSodroski
  • 2,796
  • 3
  • 24
  • 39