I had this assignment at school, wherein I had to find the output of the following C code, and also, to explain the output.
#include<stdio.h>
int i;
void fun1(void);
void fun2(void);
int main()
{
fun1();
fun2();
return 0;
}
void fun1(){
i=20;
printf("%d\t",i);
}
void fun2(){
int i=50;
printf("%d",i);
}
The output is 20 50
Because in fun1() the Global Variable 'i' is assigned to 20 and printed. And in fun2() the variable 'i' is a Local Variable, which is declared and initialized to 50, which is then printed.
I have this following question out of curiosity, how do I use the global variable 'i', in fun2()?
A simple solution would be to simply change the name and avoid the whole thing. But my curiosity is due to Java, where there is a keyword "this" to access class variable instead of a local variable.
so is there any way to do that in C?
The only way is to hide the declaration of the local variable in a code block.
For example
#include <stdio.h>
int i = 10;
void fun2( void )
{
int i = 20;
printf("local i = %d\n",i);
{
extern int i;
printf( "global i = %d\n",i);
}
}
int main(void)
{
fun2();
}
The program output is
local i = 20
global i = 10
There is no way to access a global parameter inside a function that has a local variable with the same name. It is usually bad practice to create such local variables in C though, as you saw, it is not prohibited.
In C++ you can solve it using namespaces but there is no equivalent in C.
The best way is to pass parameters to the function
void fun2(int fromExternalWorld){
int i=50;
printf("%d ",fromExternalWorld);
printf("%d\n",i);
}
int main(void)
{
fun2(i);
}
Otherwise is not possible to have two symbols with same name visible in the same scope.
You could cheat and create a pointer to the global i before declaring the local i:
void fun2( void )
{
int *ip = &i; // get address of global i
int i = 50; // local i ”shadows" global i
printf( "local i = %d, global i = %d\n", i, *ip );
}
EDIT
Seeing as this answer got accepted, I must emphasize that you should never write code like this. This is a band-aid around poor programming practice.
Avoid globals where possible, and where not possible use a naming convention that clearly marks them as global and is unlikely to be shadowed (such as prefixing with a g_ or something similar).
I can't tell you how many hours I've wasted chasing down issues that were due to a naming collision like this.
Related
I am reading a book on the C language ('Mastering C'), and found the topic on scope resolution operator (::) on page 203, on Google Books here.
But when I run the following code sample (copied from the book), the C compiler gives me an error. I searched on the internet but I am unable to find any reference to a scope resolution operator in C.
#include <stdio.h>
int a = 50;
int main(void)
{
int a =10;
printf("%d",a);
printf("%d\n", ::a);
return 0;
}
So if I want to access a global variable then how could I do that from within the main() function ?
No. C does not have a scope resolution operator. C++ has one (::). Perhaps you are (or your book is) confusing C with C++.
You asked how you could access the global variable a from within a function (here main) which has its own local variable a. You can't do this in C. It is lexically out of scope. Of course you could take the address of the variable somewhere else and pass that in as a pointer, but that's a different thing entirely. Just rename the variable, i.e. 'don't do that'
No, namespaces are a feature of C++.
It is, however, possible to refer to global a in your example.
You can achieve this by using the extern keyword:
#include <stdio.h>
int a = 50;
int main(void)
{
int a = 10;
printf("%d\n",a);
{ // Note the scope
extern int a; // Uses the global now
printf("%d\n", a);
}
return 0;
}
That's a bit tricky, though. It's bad style. Don't do that.
:: operator is available in C++ not C. If you wanted to access the global variable, use
#include <stdio.h>
int a = 50;
int main(void)
{
int a =10;
printf("%d",a); //prints 10
{
extern int a;
printf("%d", a); //prints 50
}
return 0;
}
Or you could use a pointer which holds the address of the global variable a and then dereference the pointer if you want to print the value of the global variable a.
No (the :: operator is C++ specific). In C, if you use the same identifier in different overlapping scopes (say, file scope a and block scope a), the block scope identifier shadows the file scope identifier and there is no way to refer to the shadowed identifier.
It is generally best programming practice to avoid shadowed variables. Many lint type programs can warn about this situation.
In plain C, there is no scope resolution. You have to name your variables differently.
That means that all variables a below are different ones:
#include <stdio.h>
int a = 50;
int main(void)
{
int a = 10;
{
int a = 20;
int i;
for (i = 0; i < 10; i++) {
int a = 30;
}
}
return 0;
}
You may use pointers to access and edit global variables in C.
#include <stdio.h>
#include <stdlib.h>
int a;
a=78;
int *ptr=&a; //pointer for global a
int main()
{
int a=0;
printf("%d",a); //Prints 0 as local variable
printf("%d",*ptr);
ptr=30; //changes the value of global variable through pointer
printf("%d",*ptr); //Now it prints 30
return 0;
}
It entirely depends on what kind of compiler you're using to execute your code.
#include <stdio.h>
int a = 50;
int main(void)
{
int a =10;
printf("%d\n",a);
printf("%d\n", ::a);
return 0;
}
Try running this code in Turbo C compiler, and you will get the results.
Now, regarding the C book that you're following, the examples codes present in the book must be in terms with Turbo C/C++ compiler and not the gcc compiler.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I access a shadowed global variable in C?
how to access global variable in C , if there is local variable with same name?
int m=20 ;
void main()
{
int m=30;
}
In C, you can. Of course this is just trivia, you should never do so in real life.
Declaring something extern can be done anywhere, and always links the declared variable to the global of that name.
#include <stdio.h>
int i = 3;
int main( int argc, char **argv ) {
int i = 6;
printf( "%d\n", i );
{ // need to introduce a new scope
extern int i; // shadowing is allowed here.
printf( "%d\n", i );
}
return 0;
}
In C++, the global is always available as ::i.
In C there's no way. actually, introducing an extra scope and with an extern declaration you can, see #Potatoswatter's answer.
In C++ you can look up identifiers in the global namespace using :: (as in ::m=15), which, by the way, is the same operator used to access members of "regular" namespaces (std::cout, ...).
Also, it's int main().
In C you don't. Give them a different name, it's confusing and a bad practice anyway.
same name is bad practice anyway until m is redefined you are accessing the global variable any way
int m=20 ;
void main()
{
print m // 20 would be printed here .
// max you can do
int m=30;
}
Here is my code , I want to print 15 and 12 but due to instance member hiding the local value of a is getting printed twice.
#include <stdio.h>
int a = 12;
int main()
{
int a = 15;
printf("Inside a's main local a = : %d\n",a);
printf("In a global a = %d\n",a);
return 0;
}
Why and is there any way to print it in c ? ... BTW I know it in c++.
Use the extern specifier in a new compound statement.
This way:
#include <stdio.h>
int a = 12;
int main(void)
{
int a = 15;
printf("Inside a's main local a = : %d\n", a);
{
extern int a;
printf("In a global a = %d\n", a);
}
return 0;
}
I know this doesn't directly answer your question, but the best way to do this is to change the name of the local variable so it doesn't conflict with the name of the global variable.
If you have control of the code inside the function (i.e., you can add an extern declaration to make the global variable visible), then you can just as easily change the name of the variable.
It's impossible to tell what name would be better. In practice, the variables will undoubtedly have more descriptive names than a. The way they're used should give you some guidance about good names for them.
If they actually serve the same purpose, they probably don't both need to exist. You might remove variable that's local to main(), or, perhaps better, remove the global and pass the local (or its address) to other functions that need to access it.
I think i found my answer in a way... it works
#include <stdio.h>
int a = 5;
int main()
{
int a=10;
if(1)
{
extern int a;
printf("global: %d\n", a);
}
printf("local: %d\n", a);
return 0;
}
add :: for global ambit
#include <stdio.h>
int a=12;
int main()
{
int a=15;
printf("Inside a's main local a = : %d\n",a);
printf("In a global a = %d\n",::a);
return 0;
}
I have some doubt on below code
#include<stdio.h>
int i=6;
int main()
{
int i=4;
{
extern int i;
printf("%d",i); //prints 6
}
printf("%d",i); //prints 4
}
we know that extern keyword says compiler, the variable is somewhere outside. So the question is why the extern keyword is accessing the global i variable but not the i variable which is within the main function? I was thinking there must be a contradiction because both variables are available to the inner braces as global variable. So does extern keyword access the variable which is outside the function or does it also access the variable which is outside the braces.
extern doesn't mean outside the current scope, it means an object with external linkage. An automatic variable never has external linkage, so your declaration extern int i can't possibly refer to that. Hence it's hiding it, the same as the automatic variable hid the global.
Before the printf that prints 6 you are asking the compiler to use the i defined after the #include. The closing brace then tells the compiler that the extern is no longer in effect, therefore it uses the scope where i is set to 4.
int i=4 is not global variable, if you try to access var i which is inside main in another function your compiler will thrown error about var i is undeclared. This code illustrates it.
void func() {
printf("i is %d\n",i);
}
main() {
int i=10;
func();
}
Whereas the i outside of main is global variable, which you can access in all functions.
I think you're asking whether you're right in thinking that the extern int i declaration should cause the first printf to resolve i to 4 because that int i=4 statement is in a parent scope of the scope in which the extern is declared.
The answer is no, hence the behaviour you're seeing. An extern declaration within a function is used to declare the existence of an external variable and won't ever resolve to a local variable (a variable declared within the function).
/* what Ed Heal said */
Yet, I think it would be best to illustrate it with additional example. I modified Your example to do a little more. The comments in the code tells the most of it:
#include <stdio.h>
int i = 6;
int main(void)
{
int i = 4;
printf("%d\n", i); /* prints 4 */
{
extern int i; /* this i is now "current". */
printf("%d\n", i); /* prints 6 */
{
int *x = &i; /* Save the address of the "old" i,
* before making a new one. */
int i = 32; /* one more i. Becomes the "current" i.*/
printf("%d\n", i); /* prints 32 */
printf("%d\n", *x); /* prints 6 - "old" i through a pointer.*/
}
/* The "previous" i goes out of scope.
* That extern one is "current" again. */
printf("%d\n", i); /* prints 6 again */
}
/* That extern i goes out of scope.
* The only remaining i is now "current". */
printf("%d\n", i); /* prints 4 again */
return 0;
}
How can I access a shadowed global variable in C? In C++ I can use :: for the global namespace.
If your file-scope variable is not static, then you can use a declaration that uses extern in a nested scope:
int c;
int main() {
{
int c = 0;
// now, c shadows ::c. just re-declare ::c in a
// nested scope:
{
extern int c;
c = 1;
}
// outputs 0
printf("%d\n", c);
}
// outputs 1
printf("%d\n", c);
return 0;
}
If the variable is declared with static, i don't see a way to refer to it.
There is no :: in c but you can use a getter function
#include <stdio.h>
int L=3;
inline int getL()
{
return L;
}
int main();
{
int L = 5;
printf("%d, %d", L, getL());
}
If you are talking about shadowed global var, then (on Linux) you can use dlsym() to find an address of the global variable, like this:
int myvar = 5; // global
{
int myvar = 6; // local var shadows global
int *pglob_myvar = (int *)dlsym(RTLD_NEXT, "myvar");
printf("Local: %d, global: %d\n", myvar, *pglob_myvar);
}
If you want your code to look sexy, use macro:
#define GLOBAL_ADDR(a,b) b =(typeof(b))dlsym(RTLD_NEXT, #a)
...
int *pglob_myvar;
GLOBAL_ADDR(myvar, pglob_myvar);
...
Depending on what you call shielded global variable in C, different answers are possible.
If you mean a global variable defined in another source file or a linked library, you only have to declare it again with the extern prefix:
extern int aGlobalDefinedElsewhere;
If you mean a global variable shadowed (or eclipsed, choose the terminology you prefer) by a local variable of the same name), there is no builtin way to do this in C. So you have either not to do it or to work around it. Possible solutions are:
getter/setter functions for accessing global variable (which is a good practice, in particular in multithreaded situations)
aliases to globals by way of a pointer defined before the local variable:
int noName;
{
int * aliasToNoName = &noName; /* reference to global */
int noName; /* declaration of local */
*aliasToNoName = noName; /* assign local to global */
}
what is a "shielded global variable" in pure C?
in C you have local variables, file local/global variables (static) and global variables (extern)
so file1.c:
int bla;
file2.c
extern int bla;
Yet another option is to reference the global before defining your local, or at least get a pointer to it first so you can access it after defining your local.
#include <stdio.h>
int x = 1234;
int main()
{
printf("%d\n",x); // prints global
int x = 456;
printf("%d\n",x); // prints local
}