extern global variable defined within namespace

Discussion in 'C++' started by Dan Elliott, Dec 7, 2004.

  1. Dan Elliott

    Dan Elliott Guest

    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
     
    Dan Elliott, Dec 7, 2004
    #1
    1. Advertising

  2. Dan Elliott wrote:
    > 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'.

    > main(){


    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
     
    Victor Bazarov, Dec 7, 2004
    #2
    1. Advertising

  3. Dan Elliott

    Tom Widmer Guest

    On Tue, 7 Dec 2004 08:06:40 -0600, "Dan Elliott"
    <> wrote:

    >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).

    >main(){


    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
     
    Tom Widmer, Dec 7, 2004
    #3
  4. Dan Elliott

    Dan Elliott Guest

    "Tom Widmer" <> wrote in message
    news:...
    > On Tue, 7 Dec 2004 08:06:40 -0600, "Dan Elliott"
    > <> wrote:
    >
    > >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).
    >
    > >main(){

    >
    > 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,

    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
     
    Dan Elliott, Dec 7, 2004
    #4
  5. Dan Elliott

    Tom Widmer Guest

    On Tue, 7 Dec 2004 10:44:53 -0600, "Dan Elliott"
    <> wrote:

    >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
     
    Tom Widmer, Dec 8, 2004
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Matthews
    Replies:
    5
    Views:
    2,430
    tom_usenet
    Aug 2, 2004
  2. Oodini
    Replies:
    1
    Views:
    1,775
    Keith Thompson
    Sep 27, 2005
  3. Replies:
    1
    Views:
    504
    Sion Arrowsmith
    Jul 10, 2008
  4. Simon Strandgaard

    [ruby-dl] extern a global variable?

    Simon Strandgaard, Jan 20, 2005, in forum: Ruby
    Replies:
    3
    Views:
    161
    Simon Strandgaard
    Jan 20, 2005
  5. Andre
    Replies:
    5
    Views:
    541
    Keith Thompson
    Jul 17, 2012
Loading...

Share This Page