Solved

Clarify scope and extent rules for vcpp

Posted on 1998-09-28
14
207 Views
Last Modified: 2010-04-01
I need a really clear, talking to a 4-year-old-type explanation of the uses of static and extern and other methods of making variables and constants visible from various pieces of a program.  I have been using them for months now (I thought successfully) but am getting more and more confused; each time I think I have it figured out I get some different result when I try repeating the procedure.  I will give 400 points to someone who can give me all of the information I need.
 
Include information on what order things need to be read in, if you have a variable defined in one file and want to access it from many others, where the variable should be first declared, etc.  I'm looking for a complete tutorial on using "global" vars in msvcpp5.
0
Comment
Question by:appleby
  • 8
  • 6
14 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 400 total points
ID: 1173929
I'll do my best.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173930
First of all do you know the difference between a declaration and a definition?  A declaration declares identifies the nature of a symbol, for example it can may identifies a symbol as a variable of a particular type or identifies a symbol as a function with certain parameters.  A definition on the other, hand completely defines a symbol.  A defintion for a variable provides space to store the variable and may assign the variable its intial value  A definition for a function contains the code in the function.  Since functions don't matter for this, well just concern ourselves with global variables.   In that case, a statement that does not provide storage space for a declaration and a statement that does provide space is a definition, thus

extern int someint; // Declaration.  (someint is defined elsewhere.)
int someint = 5; definition;

In C++ things can be declared multiple times, but may not be defined more than once.  (this is true of everything, not just global variables).  The above declaration for a global variable someint could appear in seperate translation units (.cpp) files.  But at most one file can contain a definition for someint (2nd line).

Note that C++ is somewhat unusual. in that the definition of a global variable is public by default.  That is, If I define a global variable

int someint;

in one translation unit (.cpp), then no other translation unit can define it.  That would be two defintions and that is not allowed.  Other translation units can define it as extern if they want to use it, (share the one already defined).  but if they don't declare it as extern, and instead try to declare their own someint, they will get linker errors.  

Now if you don't want a global varialbe to be shared in this way, you can declare it as static, like

static int someint;

In this case, the variable is not shared with other translation units.  You could have multiple translation units that all contain that same line.  Each would have their own private version of someint.

Note that this is unussual, most languages require you to take steps to share a global variable.  C++ requires you to take steps to not share it.  (However, that is not 100% true.  In order for a translation unit to access a variable declared in another, it must declare it as extern.  So it must do something either way.)

I hope this helps.  let me know if you have questions.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173931
>> if you have a variable defined in one file and want to access it
>> from many others, where the variable should be first declared, etc

Where to declare it is up to you, that is you can choose any file.  But it must be declared once (only one file may declare it).  All the others may define it as extern.

Note don't try to define it in a header (.h) file.  You can declare it there, but better not define it there.  If you declare it there, the .h file can be included in multiple translation units.  Thus each translation unit gets access to the variable.  If you define it in the header instead of declaring it, then you could only include the header file to one translation unit.  (Some people do this by mistake and then are in trouble).  Thus often there will be a header file with an extern declaration and then one .cpp file that has a definition.  then all the .cpp files (even the one with the definition) include the header file.

0
 

Author Comment

by:appleby
ID: 1173932
Thank you, this gets me well on my way.  I'd like to test things out for a little while to make sure all is clear.  For now, can you please elaborate on what makes up a "translation unit" so that I am sure I have the same understanding as you?
0
 

Author Comment

by:appleby
ID: 1173933
Did you reverse define and declare up there?  "Where to declare it is up to you, that is you can choose any file.  But it must be declared once (only one file may declare it).  All the others may define it as extern. "  I think this is backwards of what you said before.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173934
One thing I breezed over was extern.  Extern is used to make it clear when a variable is being declared instead of being defined.  It is easy to tell the difference between the defitions and declarations of classes and functions.  For example.

// function declaraition
int F(int i);   // no body--declaration.

// function definition
int F(int i)
{
   return i +1;    // Definition
}

// class declaration
class Someclass  // No body.

// Class definition
class SomeClass
{
   int i;  // definition
};

so the compiler can tell the difference between the declaration/definition of classes and functions.  Thus if I want a function to be declared in multiple translation units, I can just use its declaration.  Then one translation unit needs its definition.  

With a variable however it is hard to tell the difference between a declaration and a definition.  If the variable is being initialized, it is a definition, thus

int someint = 5;

is clearly a definition, but what about

int someint;

Is that a definition for a default constructed int?  or is it the declaration for an int that is defined in a different translation unit?  You can't tell, for sure.  Thus was decided to make that a definition.  You must use "extern" to indicate when it is a declaration.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173935
"translation unit" -- It is what is submitted to the compiler for a "single run" of the compiler.  It is ussually a .cpp and all the contents of the header (.h) files included into it.  

It is hard to tell this in the GUI age, but each .cpp file in a project is compiled seperately (as seperate translation units).  There is no interation in any way between translation units until they are linked.  That is, code on one translation unit will not affect the compilation of another but may affect the linking.  Some programmers make the mistake of using #ifndef's and other conditional code inside their .cpp files and .h files in order to try to insure that something is not defined in more than one translation unit.  That can't work.  The translation units are compiled independantly.  It can insure that it is not declared more than once for each translation unit, but cannot prevent it from being defined in more than one translation unit.

>>Did you reverse define and declare up there?  "Where to declare it
>> is up to you, that is you can choose any file.  But it  must be declared
>> once (only one file may declare it).  All the others may define it as extern. "  

Yes.  It is easy to do.  These are official terms.  You think when spending 15 years developing standards, they could have taken 10 minutes to develope terms that don't sound a like.

DEFINE it in any file you want.  DECLARE it an any others that need it.  You can declare it in the one that defines it.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:appleby
ID: 1173936
Thanks, you've been a great help.  I have to go and will read over more carefully tomorrow.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173937
May I recommend "The C++ Programming Language" by Bjarne Stroustrup.  Currrently in its 3rd edition, although maybe it could be in its 4th by now.  There is no such thing as a good C++ book, but this comes the closest.  It is not a programming book in the ussual sense. It does not teach programming.  It just teaches the use of the C++ language.  It covers this and lots of other details.  It is not difficult reading and it somehow manages to stay mildly interesting.  It makes a great reference.
0
 

Author Comment

by:appleby
ID: 1173938
Ok, one more question.  To clarify - you said you don't want to define some variable in a .h because then it can only be #included in one translation unit.  So, do I understand correctly that if you define a variable and want to use it in another translation unit, you can just declare it extern and use it, without making an sort of #include?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173939
You could do it without include files like.

//file1.cpp
int X=5;  // define.

//file2.cpp
extern int X; // declare external.
cout << X; // print X from file1.

but this gets to be a pain if lots of files need to access X, then each one has to have the extern declaration.  To make it easier, you can use an include file like

//file.h
extern int X; // declare external.

//file1.cpp
#include "file.h" // including the external declaration is not needed, but does no harm.
int X=5;  // define.

//file2.cpp
#include "file.h" // include external declaration.
cout << X; // print X from file1.

0
 

Author Comment

by:appleby
ID: 1173940
Thank you very much.  I have compiled your answers into a document that I will keep for reference.  I appreciate your thorough answers!!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1173941
This question will stay permenantly as well.  (Or at least as long as EE exists).  You can refer back to it or even post comments to it in the future.
0
 

Author Comment

by:appleby
ID: 1173942
I didn't realize you could post comments after the answer was accepted.  That is good to know!  Thanks again.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now