• Welcome to Valhalla Legends Archive.
 

Accessing one file's globals from another file

Started by tA-Kane, June 04, 2003, 04:13 AM

Previous topic - Next topic

tA-Kane

How would I access main.c's global variables from another file, say example.c?

My compiler says undefined identifier without any special accessors, and putting the global variables into a header file included by both files gives me a "multiply-defined identifier" error  :-\
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

Adron

Quote from: tA-Kane on June 04, 2003, 04:13 AM
How would I access main.c's global variables from another file, say example.c?

My compiler says undefined identifier without any special accessors, and putting the global variables into a header file included by both files gives me a "multiply-defined identifier" error  :-\

You put "extern" declarations for them in the header file. You declare them just like you do in the .c file but you put the word "extern" in front of the declaration. And remove any initializers.


tA-Kane

KBNetwork.h
 extern unsigned long   KBNetStatus;
 extern UInt32         OTVersion;

main.c
 #include "KBNetwork.h"

KBNetwork.c
 #include "KBNetwork.h"
QuoteLink Error: undefined 'KBNetStats' (data)
 Referenced from 'KBNetInit()' in KBNetwork.c
Link Error: undefined 'OTVersion' (data)
 Referenced from 'KBNetInit()' in KBNetwork.c

I don't think extern is being used properly; I've always seen it be used to identify functions, not variables, and for that matter, it's seemingly always being used to define functions which are stored in an outside library.
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

iago

Just FYI, you should never EVER use global variables across files.  The best way to do that type of thing is with accessor/mutator functions, even though those are very c++-ish :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Kp

Quote from: iago on June 04, 2003, 07:41 AM
Just FYI, you should never EVER use global variables across files.  The best way to do that type of thing is with accessor/mutator functions, even though those are very c++-ish :)
I totally disagree.  Accessing across files is perfectly sound, as long as you set up the compile environment to keep the object files synchronized (e.g. if you extend a structure definition, both files need to be recompiled or one may behave very oddly).  If the designers had meant for you never to access across files, they probably would've made "static" a default.

Kane: you did it right, but you missed a step.  Declaring something extern informs the compiler of its type and size (thus suppressing the unknown identifier error), but does not actually allocate storage for it.  So, as you posted it, both files know the type and size and both expect a third party to go to the trouble of storing it.  Note that you can declare something extern, then later create it, like so:extern int myvar;
/* stuff */
int myvar = 0xbaadf00d;

So, what you ought to do here (and I believe Adron mentioned this) is to pick one of the two files and repeat the declaration, without extern.  Thus, both files include the header and see the variable declared as extern.  One subsequently creates the variable with the non-extern declaration.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

tA-Kane

Thanks Adron and Kp, this works:

KBNetwork.h
 extern unsigned long   KBNetStatus;
 extern UInt32         OTVersion;

main.c
 #include "KBNetwork.h"

KBNetwork.c
 #include "KBNetwork.h"
 unsigned long   KBNetStatus      = 0;
 UInt32         OTVersion      = 0;
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

iago

Quote from: Kp on June 04, 2003, 01:09 PM
Quote from: iago on June 04, 2003, 07:41 AM
Just FYI, you should never EVER use global variables across files.  The best way to do that type of thing is with accessor/mutator functions, even though those are very c++-ish :)
I totally disagree.  Accessing across files is perfectly sound, as long as you set up the compile environment to keep the object files synchronized (e.g. if you extend a structure definition, both files need to be recompiled or one may behave very oddly).  If the designers had meant for you never to access across files, they probably would've made "static" a default.

Well, it IS perfectly sound from a programming perspective, but it's a problem for the same reason that making member variables in a class public.  Nothing is stopping you from doing it, but it's bad practice.  I guess this is more of a style thing than anything else, but I tend to (and, for school, have to) follow it.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Camel

you shouldn't use global variables ever for any reason! if you declare global variables, anybody who writes code that overlaps with your program can modify that variable.
pass pointers to structs or classes if you have to, it's not that big of a deal.

Yoni

Quote from: Camel on June 05, 2003, 05:17 PM
you shouldn't use global variables ever for any reason! if you declare global variables, anybody who writes code that overlaps with your program can modify that variable.
Explain?

iago

To quote my OOP prof, who was talking about why you should use private members, "You don't want just anybody playing with your privates"
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Grok

iago, please sit down, this will be difficult news to tell you.

Your professor does not know it all.

Now that you're in college, you may feel the compulsion to repeat what you've been taught there as "the truth".  When it comes to your exams, it is the truth.

Moonshine

Quoteyou shouldn't use global variables ever for any reason! if you declare global variables, anybody who writes code that overlaps with your program can modify that variable.

Now come on, never using global variables ever is just poppycock.  Also, the other person who "overlaps with your program" would have to include the file containing the global in some way, or use extern.  If this was a problem (which is shouldn't be), there's always namespaces.

iago

Quote from: Grok on June 06, 2003, 12:03 AM
iago, please sit down, this will be difficult news to tell you.

Your professor does not know it all.

Now that you're in college, you may feel the compulsion to repeat what you've been taught there as "the truth".  When it comes to your exams, it is the truth.

I actually meant that quote as a joke... "Playing with your privates" ;-)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Camel

#13
+1 to iago for the irrelivant privates comment

consider:
struct privates iagos_privates;
versus:
class privatestuff
{
public:
   bool touchiagosPrivates(...);
private:
   struct privates iagos_privates;
};

void main()
{
   class privatestuff iagosPrivateStuff;
}


in the former, anybody can say "extern struct privates iagos_privates;" and then play with iago's privates freely. in the latter, one cannot even look at iago's privates; it's sort of like wearing steel underpants.

Kp

Quote from: Camel on June 10, 2003, 05:36 PM
+1 to iago for the irrelivant privates comment

consider:
struct privates iagos_privates;
in the former, anybody can say "extern struct privates iagos_privates;" and then play with iago's privates freely. in the latter, one cannot even look at iago's privates; it's sort of like wearing steel underpants.
Just do this:static struct privates iagos_privates;Now the symbol isn't exported, so the linker won't be able to match up other people's references to it.  It doesn't protect against other accesses from the same file, but you trust the code in the same file as you - right? :)
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!