• C

Accessing global variable.

hi,
consider this program.

#include..

int global_var;

int main()
{
int global_var;
...
..
<----- At this point i want to access the global variable. Is it possible.

return 0;
}

I know one method that  uses pointers. Do u know something better.

Thanks
shaj
LVL 5
shajithchandranAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sunnycoderCommented:
without the address ( pointers ) ??

i dont think it is possible to access the global variable since local variable will take precedence
shajithchandranAuthor Commented:
well even i think the same. Just want to confirm.
Lets see if some has something to talk about this.
Kent OlsenDBACommented:

From within main() there is no way to directly address the value of the global variable *global_var*.

If you find yourself coded into a corner and discover that a function has a local variable with the same name as a global variable and you need the value of the global variable you have two real options.

1.  Rename the local variable.  In a large function this can often be a nuisance and unless you use the editor's *replace global* function you run the risk of missing some.

2.  Write another function that returns the value of a global flag.

int GlobalVar;

main()
{
  int GlobalVar;

  GlobalVar = FetchGlobalVar ();
}

int FetchGlobalVar ()
{
  return (GlovalVar);
}

Kent

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
stsanzCommented:
In C++, it would be possible to access the variable at global scope with "::global_var"
sunnycoderCommented:
2nd way was neat kent ... I liked it ...

but I feel pointers would be more elegant (and time saving) ... Shaj, why do you wish to avoid pointers ?
zebadaCommented:
This lets you "read" the global var but not change it:

int global_var=123;

int main()
{
  int a=global_var;
  int global_var;
  global_var = 5;

  printf("%d\n",global_var);
  printf("%d\n",a);
  return 0;
}

Output is
5
123

Paul
Kent OlsenDBACommented:

Hi Sunnycoder,

That's actually done quite a bit in some of the codes that I've seen.  If the compiler supports the *inline* directive, the function will execute at the same speed as any other memory access.


Hi Zebada,

Many of the older compilers won't let you do that.  (Nice trick, though.)  The compilers actually evaluate *int a=global_var;* as if it were two lines, *int a; a=global_var;*.  At which point the next line *int global_var;* generates an error because the compiler has already encountered executable code.



Of course, the real solution is not to paint yourself into this corner.  :)
Kent
grg99Commented:
No easy way, and there shouldnt be, the whole point of nested scopes is to let you declare any name without conflicting names at an outer level.

You could have declared:  int GlobalVar;  int * PtrToGlobalVar=GlobalVar;

then inside main:  #define GimmeOuterGlobalVar   (*PtrToGlobalVar)



GaryFxCommented:
The real answer is to avoid global variables.  This principle is about thirty years old, based on a paper by Drs. William Wulf and Mary Shaw, "Global variables considered harmful," Sigplan Notices, 8(2):28--34, February 1973.   If you need a more detailed explanation as to why, then ask or do a web search, as there's plenty of existing online discussion.

In other words, rather than asking how to access the global, the better solution is to get rid of it entirely.  If necessary, create a separate module with access functions and the variable declared static at file scope.

Gary
Kent OlsenDBACommented:


Global variables are sometimes a necessary evil.

Some languages (like COBOL, of which more than 80% of all financial applications are STILL written in) don't have local variables, except for externally written functions.

Other languages deal exclusively with local variables.

Then there is C and its derivatives which liberally support both global and local variables.  Some global variables are unlikely to ever go away (stdin, stdout, stderr, etc.).  But it should be noted that one of the most important global variables is being deprecated.  *errno* is a global and externally linkable integer than contains the last error code issued by the C runtime library.  GetLastError() is now the preferred way to get the error code.


For my applications, global variables are just that.  Something that beyond a doubt is required throughout the program like file handles and streams.  Note that all streams aren't necessarily global, but if the result of executing a program is that it produces a particular output file then the stream associated with that file is likely global in scope even if it declared local to main() and passed to all of the subfunctions.

Kent
SalteCommented:
It's not possible to access the global variable once you declare a local variable with the same name except through a
pointer.

In C++ it is possible using the global scope operator but C doesn't have such an operator.

As a general rule you should avoid global variables, use them only when you have to.

In C++ they can largely be avoided since you can declare static class variables instead which serves much the same purpose but which do not lay themselves open for modification by anyone.

In C you cannot do that - although I have seen that C99 appear to have some support fo nnamespaces I am not sure exactly how much support they have for them and in particular I don't know if they have introduced the scope operator to C as it is used in C++. Without the scope operator you can't access a global variable which is hidden
by a local variable unless you have a pointer that is already pointing to it.

Hope this explains.

Alf
GaryFxCommented:
> GetLastError() is now the preferred way to get the error code.

In ANSI C?  I thought GetLastError was a Microsoft invention, non-standard, and not part of C.

errno is actually a macro on many platforms, because the original implementations weren't thread safe.

Gary

Kent OlsenDBACommented:

Yeah, I jumped the gun a bit here.  GetLastError() is a MS invention (abortion?) that seems to be gaining more and more favor.  It's not ANSI and not directly supported by Borland (not that they're able to influence the standards much anymore).

But because MS does it, everyone will have to before long.

sigh...

SalteCommented:
Note that also on linux and other systems you will often find that 'errno' isn't a simple global variable. Having it as global variable cause troubles when you use threads. It could be defined as a thread local variable and that is actually often what is done but it isn't declared as a global variable any more.

'errno' is more often than not a macro which expands to a function call which returns the address of a per thread errno variable.

Something like this:

#define errno (*errno_function())

The 'errno_function' might even have arguments such as current thread id although most systems have system calls to get that so the function can do it on its own.

It should be noted that in ANSI C the errno variable is still the preferred ANSI way to get error code. MS want you to use GetLastError() partly due to the thread problem (which can be circumvented as I described above) but mostly because adhering to standards is against their company policy. For example GetLastError will return more detailed error codes as well as it can support error codes from other components. For example if DirectX or COM detect an error they can set GetLastError to values without conflict with the system since the value returned from GetLastError is a 32 bit value which is separated into several different bit fields, one of those fields identify the 'system' that generated or detected the error, Windows is only one such system (with identification 0) but you can easily find several others if you look around in header files ;)

Use of GetLastError does not make portable code though. If you write MFC or other MS specitic code then GetLastError is indeed the preferred way since you can't port such code anyway (and if you can it's because you use a package which emulates windows on the other OS, that system would probably also emulate GetLastError()).

For portable programs you would use errno exactly. Even in threaded programs where it most likely isn't a simple variable even if it appears to be ;) (preprocessor is a 'wonderful' thing).

Alf
shajithchandranAuthor Commented:
Thanks for all those comments.
I know that using global variable is harmful. But this is a common interview question so i thought of finding some other good methods.

THANKSSSSSSSSSSSSSSS


hi zebada,

>>This lets you "read" the global var but not change it:
Well this trick will alllow me only to read the initial value. Once the value of the global variable is changed u cannot use it.
So i thnk it won't be helpful.

hi GaryFx,
>>paper by Drs. William Wulf
Can u give me more details. I will give u points.
shajithchandranAuthor Commented:
one more doubt.
In c++.

int global; <-----------first

int main()
{
int global;

{
int global;
::global;  <---------------Will this still access the access the first global variable.

}
return 0;
}
Kent OlsenDBACommented:

As stanz pointed out, the "::" causes the compiler to NOT search up the variable stack for the closest reference, but to go directly to the global block for the variable.


Kent
SalteCommented:
prefix :: is the global scope operator, so it ignores any local variables and looks for the variable in the global variable space directly.

infix :: uses the scope specified by the left hand side and looks for the name on the right hand side in that scope.

so ::bar is a global bar.

foo::bar is a bar defined in the foo scope.

bar is a global bar or local bar depending on which is nearest when you look at it from innermost scope to outermost scope (global scope). The first bar it finds is the bar that is chosen.

Alf
GaryFxCommented:
>  this is a common interview question so i thought of finding some other good methods.

If I were asking it as an interview question, the answer I'd hope to get is "Don't."  

Gary
shajithchandranAuthor Commented:
Thanks again.
SalteCommented:
Agree with Gary there.

If anyone around me program like that I will personally scold him ;) If I have any say in the matter he will have to clean up ihis act fast or get the boot ;)

rule 1. Use global variables as little as possible and only when all other options are out.
rule 2. When you use global variables, declare them all at a proper place in the source code so they are easily found and easily seen. If some global variables work together you might consider grouping them together in the declaration. However, a better idea would be to put them in a class in C++ or in a module in C and let that module be the only module to access them, so they are declared in a single module together which has little else other than these global variables and the functions to access them.

rule 3. Name all global variables with a proper prefix to mark them as global (this is for C, in C++ you would place global variables as static variables in a class and give them S_ or s_ prefix). In C you should give them G_ or g_ prefix so that they are clearly marked as global variables. Any local variable should NEVER have M_ m_ G_ g_ S_ or s_ prefix so
there are never any danger of name clash between global and local variables.

Alf
shajithchandranAuthor Commented:
hi Salte,
Thanks for those words of advice.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.