Re: just C++ in xcode
Re: just C++ in xcode
- Subject: Re: just C++ in xcode
- From: Andreas Grosam <email@hidden>
- Date: Thu, 29 Sep 2005 15:07:48 +0200
On 29.09.2005, at 05:53, Marshall Clow wrote:
Maybe this is a C++ question not having to do with
xcode, but I'm desparate...
If I have a named namespace in foo1.h:
namespace myspace
{
int myvar;
};
and in foo1.cpp:
#include foo1.h
using namespace myspace;
myvar=1;
and in foo2.cpp
#include foo1.h
using namespace myspace;
cout<<myvar;
If the code in foo1.cpp executes before foo2.cpp, why
should I not find myvar has a value of 1 in foo2?
You've declared two variables.
"extern" is your friend here.
--
-- Marshall
hm...
Although it is pretty off topic, in fact it is a nice example :-)
And i guess, you both missed something!
Firstly, the variable
myspace::myvar has
external linkage, which means, that there is only one entity with name
myspace::myvar - and it can be accessed from foo1.cpp as well as from foo2.cpp.
Secondly, in foo1.cpp the statement
myvar = 1;
isn't an
expression statement, but a
declaration statement, which introduces a new variable
myvar in global namespace with no type (which is illegal in C++). It does not "initialize" the variable
myspace::myvar as it might be expected.
In order to fully understand the problem you need to become familiar with the concepts of
1) translation unit
2) scopes
3) namespaces
4) linkage
5) declaration vs definition and ODR (one definition rule)
and a bunch of C++ rules.
To explain this in its whole extent is beyond this scope, though.
Just in brief (and this became pretty long anyway):
1)
In your example you have two translation units: foo1.cpp and foo2.cpp which will be compiled independently. Say, these are TU1 and TU2.
A TU contains a set of
declarations.
3)
A namespace N denotes a certain scope. Any entity declared in a namespace-body, are said to be a member of this namespace. A name declared inside a namespace has "namespace-scope". All other entities not declared in any namespace have "global-scope". (note that there are more scopes, like class scope, etc)
(An entity is a value, object, subobject, base class subobject, array element, variable, function, instance of a function, enumerator, type, class member, template, or namespace.)
4)
A name has a "linkage" if it may denote the same entity declared in another scope, otherwise it has "no linkage".
There are two types of linkage:
1. external linkage:
The entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
2. internal linkage:
The entity it denotes can be referred to by names from other scopes in the same translation unit (but not across different TUs).
When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
Well, entities beeing *objects* having *namespace scope* - like the global variable
myvar in the example -
have
internal linkage, if
- explicitly declared
static or,
- are a constant, declared with
const and have neither been declared
extern nor previously declared
extern,
otherwise they have
external linkage.
5)
A
declaration just introduces (or redeclares) a name into a TU, but does not "materialize" an entity.
However, there are declarations which also define an entity:
For names denoting an object a declaration is also a
definition unless the
extern specifier is used:
These are all definitions:
int a; // yes, this too -- because it's C++ and not C!
extern const int b = 0; // explicit initialization
namespace N { int x; } // defines N and N::x
These are all declarations:
extern int a;
extern const int b;
using N::x;
Some additional notes: the prozess of intialization is somewhat more complex.
The expression on the right side of the "=" is called
initializer-clause.
If there is no explicit initializer in a
definition, a "default-initializer" is applied. If the object of type T is a scalar type, the object is
zero-initalized, means, that it gets the value 0 converted to T. This happens before the function
main() is entered.
In your example,
myspace::myvar will be initialized to 0.
The One Definition Rule:
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.
This is illformed:
namespace n {
int x;
};
int n::x = 1;
The reason is, that there are two definitions for the same name referring to the same entity.
In your example, it follows that the variable
myvar in namespace
myspace has
external linkage. This means in turn, that TU1 and TU2 refer to the same entity - you didn't create two entities!
If you write
namespace n {
int x;
};
using namespace n;
x = 1;
The statement above
x = 1;
actually introduces a new variable in global space which does not have a type. Introducing a variable with no type should be rejected by the compiler.
In your example, note that the variable
myspace::myvar is initialized to 0. This happens before the main() function gets executed.
if you write
namespace n {
extern int x;
};
Like without "extern", the variable has external linkage!
However, it is not a definition anymore! It is just a declaration. It does not *define* the entity
n::x and thus it must be defined elsewhere, writing
long n::x = 1;
When writing:
using namespace n;
long x = 1;
in order to initialize the variable
n::x, this is not appropriate! You instead introduce a new variable
x in global space, and there is still no definition for
n::x.
The next interesting question is, when using the declaration of
n:x with
extern above, and link two TUs together, each defining the variable (object)
x::n and initializing it with different values. Guess what happens?
For the solution you may cite the C++ standard, 3.2.3 ;-)
Regards
Andreas
Marshall Clow Idio Software <mailto:email@hidden>
It is by caffeine alone I set my mind in motion.
It is by the beans of Java that thoughts acquire speed,
the hands acquire shaking, the shaking becomes a warning.
It is by caffeine alone I set my mind in motion.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden