extern global variable defined within namespace

D

Dan Elliott

Hello,

Converting from a working C program to C++, I run into the following error:

I have a header: (header.h)

namespace shared{
...
struct X{
...
};
extern X a;
}

In a .cc file I have:

using namespace shared;
X a;
main(){
....
}

The compiler tells me that a is ambiguous.

If I modify header.h to have extern X a outside of the "shared" namespace or
modify the .cc file to look like:

shared::X a;
main(){
....
}

There are no complaints.

However, there are no assurances that the second solution (modification of
the .cc file) is actually declaring my global variable. It may be simply
creating another file-level variable thinking shared::X is supposed to
resolve to the struct X in the same namespace. How should I tell the
compiler I am trying to declare the global variable "a" in my .cc file?

By the way, I am using VisualAge C++ Professional / C for AIX Compiler,
Version 5.

Thank you for your time.

- dan elliott
 
V

Victor Bazarov

Dan said:
Converting from a working C program to C++, I run into the following error:

I have a header: (header.h)

namespace shared{
...
struct X{
...
};
extern X a;

This declares 'shared::a' as an object of type 'shared::X', defined
_elsewhere_. This object has external linkage, and will be accessible
from any module that includes this header.
}

In a .cc file I have:

using namespace shared;
X a;

That declares and defines '::a' as an object of type 'shared::X', since
'shared::X' is made visible by the 'using' directive.

So, at this point there are two objects that can be found by name lookup
if you just use the unqualified name 'a', 'shared::a' and '::a'.

Should be

int main() {

.. Doesn't your compiler complain?

What's there?
}

The compiler tells me that a is ambiguous.

Where does it tell you? Which line does it complain about?
If I modify header.h to have extern X a outside of the "shared" namespace or
modify the .cc file to look like:

shared::X a;
main(){

Again,

int main() {

.. Get into habit of writing correct C++ here, please.
...
}

There are no complaints.

Of course. '::a' is declared in the header, '::a' is defined in the
source module, they are one and the same object.
However, there are no assurances that the second solution (modification of
the .cc file) is actually declaring my global variable.

Not sure what you mean here.
It may be simply
creating another file-level variable thinking shared::X is supposed to
resolve to the struct X in the same namespace. How should I tell the
compiler I am trying to declare the global variable "a" in my .cc file?

There is no sure way except

extern shared::X a = shared::X();

which will let you sleep better at night knowing that you [again] declared
a global object of type 'shared::X' that has external linkage.

V
 
T

Tom Widmer

Hello,

Converting from a working C program to C++, I run into the following error:

I have a header: (header.h)

namespace shared{
...
struct X{
...
};
extern X a;
}

In a .cc file I have:

using namespace shared;
X a;

The above declares and defines a global variable called "a". It
doesn't define shared::a. You can't define a variable outside its
namespace unless you use a nested name specifier (e.g. shared::a).

What does main return? I'm amazed your compiler compiles that without
error or warning, since an implicit int return type has never been
part of C++.
...
}

The compiler tells me that a is ambiguous.

Presumably when you try to use it in main? You can refer to the global
one with ::a, and the shared one with shared::a (with the latter
giving a linker error unless you've defined shared::a elsewhere).
If I modify header.h to have extern X a outside of the "shared" namespace or
modify the .cc file to look like:

shared::X a;

That declares and defines another global variable "a" of type
shared::X.
main(){
...
}

There are no complaints.

Right, since now you are using the global "a", and never touch the
shared one.
However, there are no assurances that the second solution (modification of
the .cc file) is actually declaring my global variable.

Why not? You are using the syntax to declare a global variable, so
that's what it will do.

It may be simply
creating another file-level variable thinking shared::X is supposed to
resolve to the struct X in the same namespace.

shared::X does resolve to shared::X! But you can declare objects of
type shared::X in other namespaces, including the global one.

How should I tell the
compiler I am trying to declare the global variable "a" in my .cc file?

With:

shared::X a;

I am right in saying that you want two "a" variables? Your post is
quite ambiguous over whether you are trying to define shared::a or
declare and define an unrelated global ::a.

Tom
 
D

Dan Elliott

Tom Widmer said:
The above declares and defines a global variable called "a". It
doesn't define shared::a. You can't define a variable outside its
namespace unless you use a nested name specifier (e.g. shared::a).


What does main return? I'm amazed your compiler compiles that without
error or warning, since an implicit int return type has never been
part of C++.


Presumably when you try to use it in main? You can refer to the global
one with ::a, and the shared one with shared::a (with the latter
giving a linker error unless you've defined shared::a elsewhere).


That declares and defines another global variable "a" of type
shared::X.


Right, since now you are using the global "a", and never touch the
shared one.


Why not? You are using the syntax to declare a global variable, so
that's what it will do.

It may be simply

shared::X does resolve to shared::X! But you can declare objects of
type shared::X in other namespaces, including the global one.

How should I tell the

With:

shared::X a;

I am right in saying that you want two "a" variables? Your post is
quite ambiguous over whether you are trying to define shared::a or
declare and define an unrelated global ::a.

Tom,

Thanks for the education. I am slowly getting there.

I do not want a global and local version of "a." Instead, I want to declare
the global variable "a." in my .cc file. Would it be easier (and legal) to
declare this in my header file inside the namespace? Otherwise, I am
unclear on how to specify that I want to declare THE GLOBAL VARIABLE in my
..cc file. Would it look something like:

shared::X shared::a <some_value>

Thank you,

dan elliott
 
T

Tom Widmer

I do not want a global and local version of "a." Instead, I want to declare
the global variable "a." in my .cc file. Would it be easier (and legal) to
declare this in my header file inside the namespace? Otherwise, I am
unclear on how to specify that I want to declare THE GLOBAL VARIABLE in my
.cc file. Would it look something like:

shared::X shared::a <some_value>

You have some major terminology problems that have confused me. Both
of your a's are global variables (that is, namespace scope). One is in
the global namespace, one in the shared namespace, but there is
nothing "local" about either. Local variables are function scope
variables.

To get back to what I now realise you want (that is, one object called
"a", in the shared namespace), then your definition is about right.
something like:

shared::X shared::a(constructor params);
or
shared::X shared::a = initializer expression;
or
shared::X shared::a; //default constructed

or (probably better), reopen the namespace:

namespace shared
{
X a; //or provide constructor params or an initializer
}

Note that global variables are not often the best way of doing things
in C++. Singletons are a more common way.

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top