extern global variable defined within namespace

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Elliott

    #1

    extern global variable defined within namespace

    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


  • Victor Bazarov

    #2
    Re: extern global variable defined within namespace

    Dan Elliott wrote:[color=blue]
    > 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;[/color]

    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.
    [color=blue]
    > }
    >
    > In a .cc file I have:
    >
    > using namespace shared;
    > X a;[/color]

    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'.
    [color=blue]
    > main(){[/color]

    Should be

    int main() {

    .. Doesn't your compiler complain?
    [color=blue]
    > ...[/color]

    What's there?
    [color=blue]
    > }
    >
    > The compiler tells me that a is ambiguous.[/color]

    Where does it tell you? Which line does it complain about?
    [color=blue]
    >
    > 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(){[/color]

    Again,

    int main() {

    .. Get into habit of writing correct C++ here, please.
    [color=blue]
    > ...
    > }
    >
    > There are no complaints.[/color]

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

    Not sure what you mean here.
    [color=blue]
    > 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?[/color]

    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.
    [color=blue]
    > [...][/color]

    V

    Comment

    • Tom Widmer

      #3
      Re: extern global variable defined within namespace

      On Tue, 7 Dec 2004 08:06:40 -0600, "Dan Elliott"
      <dan_elliott_at _cox_dot_net@no Spam.org> wrote:
      [color=blue]
      >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;[/color]

      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).
      [color=blue]
      >main(){[/color]

      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++.
      [color=blue]
      >...
      >}
      >
      >The compiler tells me that a is ambiguous.[/color]

      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).
      [color=blue]
      >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;[/color]

      That declares and defines another global variable "a" of type
      shared::X.
      [color=blue]
      >main(){
      >...
      >}
      >
      >There are no complaints.[/color]

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

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

      It may be simply[color=blue]
      >creating another file-level variable thinking shared::X is supposed to
      >resolve to the struct X in the same namespace.[/color]

      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[color=blue]
      >compiler I am trying to declare the global variable "a" in my .cc file?[/color]

      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

      Comment

      • Dan Elliott

        #4
        Re: extern global variable defined within namespace


        "Tom Widmer" <tom_usenet@hot mail.com> wrote in message
        news:f9hbr09i6h u9f4jmgtcbfcnkl 5n8ahaoj3@4ax.c om...[color=blue]
        > On Tue, 7 Dec 2004 08:06:40 -0600, "Dan Elliott"
        > <dan_elliott_at _cox_dot_net@no Spam.org> wrote:
        >[color=green]
        > >Hello,
        > >
        > >Converting from a working C program to C++, I run into the following[/color][/color]
        error:[color=blue][color=green]
        > >
        > >I have a header: (header.h)
        > >
        > >namespace shared{
        > > ...
        > > struct X{
        > > ...
        > > };
        > > extern X a;
        > >}
        > >
        > >In a .cc file I have:
        > >
        > >using namespace shared;
        > >X a;[/color]
        >
        > 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).
        >[color=green]
        > >main(){[/color]
        >
        > 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++.
        >[color=green]
        > >...
        > >}
        > >
        > >The compiler tells me that a is ambiguous.[/color]
        >
        > 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).
        >[color=green]
        > >If I modify header.h to have extern X a outside of the "shared" namespace[/color][/color]
        or[color=blue][color=green]
        > >modify the .cc file to look like:
        > >
        > >shared::X a;[/color]
        >
        > That declares and defines another global variable "a" of type
        > shared::X.
        >[color=green]
        > >main(){
        > >...
        > >}
        > >
        > >There are no complaints.[/color]
        >
        > Right, since now you are using the global "a", and never touch the
        > shared one.
        >[color=green]
        > >However, there are no assurances that the second solution (modification[/color][/color]
        of[color=blue][color=green]
        > >the .cc file) is actually declaring my global variable.[/color]
        >
        > Why not? You are using the syntax to declare a global variable, so
        > that's what it will do.
        >
        > It may be simply[color=green]
        > >creating another file-level variable thinking shared::X is supposed to
        > >resolve to the struct X in the same namespace.[/color]
        >
        > 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[color=green]
        > >compiler I am trying to declare the global variable "a" in my .cc file?[/color]
        >
        > 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.[/color]

        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


        Comment

        • Tom Widmer

          #5
          Re: extern global variable defined within namespace

          On Tue, 7 Dec 2004 10:44:53 -0600, "Dan Elliott"
          <dan_elliott_at _cox_dot_net@no Spam.org> wrote:
          [color=blue]
          >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>[/color]

          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(const ructor 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

          Comment

          Working...