Topic: Scope of static const member identifier


Author: David R Tribble <david@tribble.com>
Date: 1999/07/15
Raw View
wmm@fastdial.net wrote:
>
> In article <Q23h3.30804$Gh.1034401@newscene.newscene.com>,
>   "Al Stevens" <alstevens@midifitz.com> wrote:
> > I want to make sure I got this right and not that my compiler is
> > leading me astray. Given:
> >
> > class foo {
> >     static const n = 5;
> >     static int bar[];
> >     // ...
> > };
> >
> > Is the following definition of foo::bar OK? (egcs 1.1.1 thinks so.)
> >
> >     int foo::bar[n];
>
> Yes, this is fine.
[...]
>
> > I can infer the answers to these questions based on the behavior of
> > one compiler, but I'd prefer to see that behavior validated by the
> > standard.
> >
> > 9.4.2 says, "The initializer expression in the definition of a
> > static data member is in the scope of its class." But it does not
> > mention the constant-expression that specifies the dimension of a
> > static array member.
> >
> > 1. Is there someplace else where this is specified?
>
> Yes.  3.3.6p1, point 5, and 3.4.1p12, which refers back to
> 3.4.1p8.

Essentially, the '[' opens the scope of foo::bar so that the insides
of foo are visible.  The same is true of initializers, where the
contents between the '{' and '}' have access to the parent class
scope of the variable being initialized:

    class Foo
    {
        enum Color { RED, BLUE, GREEN };
        static Color  colors[];
        int           bar(Color c);
    };

    /*static*/ Foo::Color  colors[3] = { RED, BLUE, GREEN };

We don't need to write 'Foo::RED' et al.

This is also true of the parameter declarations between the '('
and the ')' in a function declaration.

    int Foo::bar(Color c)   // Don't need 'Foo::Color c'
    { ... }

-- David R. Tribble, david@tribble.com --


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: wmm@fastdial.net
Date: 1999/07/18
Raw View
In article <378D189C.5A568D86@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
>
> Essentially, the '[' opens the scope of foo::bar so that the insides
> of foo are visible.  The same is true of initializers, where the
> contents between the '{' and '}' have access to the parent class
> scope of the variable being initialized:

Well, not exactly.  It's the "foo::bar" in the declarator that
opens the scope of foo in a function or static data member
definition.  Again, see 3.3.6p1, point 5.

>     class Foo
>     {
>         enum Color { RED, BLUE, GREEN };
>         static Color  colors[];
>         int           bar(Color c);
>     };
>
>     /*static*/ Foo::Color  colors[3] = { RED, BLUE, GREEN };
>
> We don't need to write 'Foo::RED' et al.

No, but you do need to write "Foo::colors" -- the Foo::Color doesn't
open the scope of Foo because it's part of the type specifier, not
part of the declarator.

> This is also true of the parameter declarations between the '('
> and the ')' in a function declaration.
>
>     int Foo::bar(Color c)   // Don't need 'Foo::Color c'
>     { ... }
>
> -- David R. Tribble, david@tribble.com --

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 1999/07/13
Raw View
In article <7m9215$k1j$1@nnrp1.deja.com>,
  Andrei Alexandrescu <andrewalex@hotmail.com> wrote:
> In article <7m4nee$85q$1@nnrp1.deja.com>,
>   wmm@fastdial.net wrote:
> [size of static array component is looked up in the class definition]
>
> By the way, does this apply to template parameters, too? Consider
this:
>
> namespace N
> {
>     enum E { e1 };
>     template <E e> class A { };
> }
>
> typedef N::A<e1> A1;
>
> CodeWarrior Pro 4 rejects the code. It requires e1 to be prefixed with
> N::.
>
> I have two suspicions:
>
> 1. The code is not valid;

That's correct, the code is not valid.  It has nothing to do
with template parameters, though, it's the fact that the qualified
name appears in a type specification, not in a declarator.  You
only "open up" the scope identified in a nested name specifier if
it appears in a declarator.  So, for instance, if you have

 class C {
     typedef int I;
     I f();
 };

 C::I C::f() { }

both "C::"s are required; the fact that "C::" appeared in the
type specifier has no effect on how subsequent names are looked
up; only the "C::" in the declarator pervades the entire following
declaration.

> 2. The code should better be valid.
>
> I hate this.

I'm sorry you're unhappy, but I think it was the right choice.

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/07/09
Raw View
I want to make sure I got this right and not that my compiler is leading me
astray. Given:

class foo {
    static const n = 5;
    static int bar[];
    // ...
};

Is the following definition of foo::bar OK? (egcs 1.1.1 thinks so.)

    int foo::bar[n];

Or should it be this?

    int foo::bar[foo::n];

Three questions:

1. Is the constant-expression for a static array's dimension in the scope of
the array's class?
2. May that expression reference private members of the class?
3. If the answers to 1 and 2 are "yes," what if n is also defined in an
outer scope with a different value?

I can infer the answers to these questions based on the behavior of one
compiler, but I'd prefer to see that behavior validated by the standard.
9.4.2 says, "The initializer expression in the definition of a static data
member is in the scope of its class." But it does not mention the
constant-expression that specifies the dimension of a static array member.

Three more questions:

1. Is there someplace else where this is specified?
2. If not, is the specification in 9.4.2 considered to be sufficient?
2. If not, is a defect report needed?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 1999/07/09
Raw View
In article <Q23h3.30804$Gh.1034401@newscene.newscene.com>,
  "Al Stevens" <alstevens@midifitz.com> wrote:
> I want to make sure I got this right and not that my compiler is
leading me
> astray. Given:
>
> class foo {
>     static const n = 5;
>     static int bar[];
>     // ...
> };
>
> Is the following definition of foo::bar OK? (egcs 1.1.1 thinks so.)
>
>     int foo::bar[n];

Yes, this is fine.

> Or should it be this?
>
>     int foo::bar[foo::n];
>
> Three questions:
>
> 1. Is the constant-expression for a static array's dimension in the
scope of
> the array's class?

Yes.

> 2. May that expression reference private members of the class?

Yes.

> 3. If the answers to 1 and 2 are "yes," what if n is also defined in
an
> outer scope with a different value?

Doesn't matter.  The lookup for unqualified names says that the
class member name hides names declared outside the class.

> I can infer the answers to these questions based on the behavior of
one
> compiler, but I'd prefer to see that behavior validated by the
standard.
> 9.4.2 says, "The initializer expression in the definition of a static
data
> member is in the scope of its class." But it does not mention the
> constant-expression that specifies the dimension of a static array
member.
>
> Three more questions:
>
> 1. Is there someplace else where this is specified?

Yes.  3.3.6p1, point 5, and 3.4.1p12, which refers back to
3.4.1p8.

> 2. If not, is the specification in 9.4.2 considered to be sufficient?

N/A.

> 2. If not, is a defect report needed?

No.

--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/10
Raw View
On 09 Jul 99 11:47:43 GMT, wmm@fastdial.net <wmm@fastdial.net> wrote:
>  "Al Stevens" <alstevens@midifitz.com> wrote:

>> 1. Is the constant-expression for a static array's dimension in the
>> scope of the array's class?
>
>Yes.

Indeed, if we have a function X::F that takes as its argument a nested
class X::in, and returns a nested class X::out, then this class X
resides in namespace N --
   namespace N {
      struct X { struct in{}; struct out{}; out F(in) const; };
   }
then we can define function N::X::F outside the namespace N as
   N::X::out N::X::F(in) const { return out(); }
Note that we said just "in" and not "N::X::in".



>> 2. May that expression reference private members of the class?
>
>Yes.

Indeed, this is useful because we may want to use a private
constructor to initialize a variable.


>> 3. If the answers to 1 and 2 are "yes," what if n is also defined in
>> an outer scope with a different value?
>
>Doesn't matter.  The lookup for unqualified names says that the
>class member name hides names declared outside the class.

If you want to use the global N or the N in the unnamed namespace of
the cpp file, then you have to say "::N".  That is, you have to fully
namespace-qualify the variable name.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Andrei Alexandrescu <andrewalex@hotmail.com>
Date: 1999/07/11
Raw View
In article <7m4nee$85q$1@nnrp1.deja.com>,
  wmm@fastdial.net wrote:
[size of static array component is looked up in the class definition]

By the way, does this apply to template parameters, too? Consider this:

namespace N
{
    enum E { e1 };
    template <E e> class A { };
}

typedef N::A<e1> A1;

CodeWarrior Pro 4 rejects the code. It requires e1 to be prefixed with
N::.

I have two suspicions:

1. The code is not valid;
2. The code should better be valid.

I hate this.

Andrei


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]