Re: [sv-ec] Protection of class types


Subject: Re: [sv-ec] Protection of class types
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Fri Mar 21 2003 - 15:33:06 PST


> From: "Arturo Salz" <Arturo.Salz@synopsys.com>
>
> Kevin,
>
> Take a look at: http://gcc.gnu.org/ml/gcc-bugs/2002-05/msg01168.html

That refers to gcc 2.95, I was using 3.2 on RedHat Linux 8.0.
 
> I don't know if this has been fixed in your version of g++ (you seem to
> imply that they have). If it hasn't been fixed then your test case would
> still work. To verify this you'd need to generate a compiler error by
> attempting to use a private class in an illegal context.

Yep, it does give an error if you try using Nested outside Goo.
 
> Also, I don't understand how your code can be correct. If Goo:Nested
> is private, how can "Nested* foo()" be declared public? If the return type
> is not visible outside Goo, how can the constructor be public? This all
> seems rather suspicious.

G++ will tell you if everything is private - the class is practically unusable.

The methods in the class need to be public to be usable by the parent, but
since the class itself is private to the parent you can only use it in the
parent class (limited publicity?).

> Finally, if we do as Michael suggested then we aren't creating any backward
> compatibility issues. The only difference will be that an attempt to protect
> a class will currently result in a compiler error, and in an upcoming release
> the error may not occur. This is an observable difference, but hardly a
> backward compatibility issue.
>
> Arturo

It wasn't clear to me what Michael was proposing.

Kev.

>
> ----- Original Message -----
> From: "Kevin Cameron x3251" <Kevin.Cameron@nsc.com>
> To: <sv-ec@eda.org>; <Arturo.Salz@synopsys.COM>
> Sent: Friday, March 21, 2003 10:16 AM
> Subject: Re: [sv-ec] Protection of class types
>
>
> > From: "Arturo Salz" <Arturo.Salz@synopsys.com>
> >
> > Hi All,
> >
> > I looked at the issue of protecting types (or nested classes) in C++ and
> > whether we should enable that feature in SystemVerilog-3.1.
> >
> > The first question is straightforward. C++ does allow nested classes and
> > other type declarations to be declared private/protected/public. Unlike
> > data members, which are private by default, types are public by default.
> >
> > After examining the issue closer, the ability to protect nested classes does
> > create some undesirable complexity. Consider the following C++ class:
> >
> >
> > ------------------------------------------------------------------------------
> --
> >
> > class Goo
> > {
> > private:
> > class Nested { ... };
> > Nested *foo();
> > };
> >
> > If you don't include the implementation of foo in the declaration, and try to
> > define it out-of-body, like this:
> >
> > Nested *foo() { .... }
> >
> > Generates a compiler error since Nested is not visible at the top level.
> > If we write:
> >
> > Goo::Nested *foo() { .... }
> >
> > That doesn't work either since foo is private to Goo.
> > If we write:
> >
> > Goo::Nested *Goo::foo() { ... }
> >
> > That doesn't work!
>
> I tried this code (test.cpp) -
>
> class Goo
> {
> private:
> class Nested {
> int bar();
> public:
> Nested();
> private:
> };
> Nested y;
> public:
> Nested *foo();
> };
>
> main()
> {
> Goo x;
> }
>
> with "g++ -c test.cpp" (v 3.2) and then did "nm -C test.o" which gives -
>
> U __gxx_personality_v0
> 00000000 T main
> U Goo::Nested::Nested[in-charge]()
> 00000000 W Goo::Goo[in-charge]()
>
> So the constructor syntax is:
>
> Goo::Nested::Nested()
> {
>
> }
>
> and bar() is:
>
> int Goo::Nested::bar()
> {
> }
>
> Nested is still private to Goo.
>
>
> > The problem is that class Nested is now private to Goo, thus, only members
> > of Goo can access the type! Thus, this function can only be defined inside
> > the declaration of Goo, but not anywhere else outside.
> >
> > In C++, the only way one can get around these restrictions is by changing foo
> > from a function to a task that takes a reference to a Nested pointer as a
> parameter:
> >
> > class Goo
> > {
> > private:
> > class Nested { ... };
> > void *foo(Nested *&);
> > };
> >
> > Now, foo can be declared out-of-body, thus:
> >
> > void Goo::foo(Nested *& p) { p = new Nested; }
> >
> > which, is roughly equivalent to:
> > Goo::Nested* Goo::foo() { return new Nested; }
> >
> > The difference is that Goo::Nested is no longer at file scope, but inside the
> > scope of a member of class Goo .
> >
> > ------------------------------------------------------------------------------
> --
> >
> >
> > It is this kind of complexity that caused the gnu folks to relax the type
> checking
> > in gcc and break with the standard by simply making all class-nested types
> public.
>
> The nested classes are not necessarily public with version 3.2 of g++.
>
> > Therefore, I recommend that class-nested types in SystemVerilog-3.1 remain
> > public. No decision that we make today will limit in any way our ability to
> add this
> > feature in a future release. Right now we can choose to make it an error to
> prefix a
> > type declaration with the protected or local keywords (the current proposal),
> or we
> > can allow these keywords and ignore them (as gcc has been doing).
> >
> > Arturo
>
> While I'm not too bothered about privacy myself, I would disagree with "No
> decision that
> we make today will limit..." since making them private in future would not be
> backward
> compatible. Since G++ is probably the world's most popular C++ compiler I'd
> suggest
> doing whatever it does.
>
> Regards,
> Kev.
>
> PS: This works in g++
>
> class Goo
> {
> private:
> class Nested {
> class Sub {
> public:
> Sub();
> private:
> };
> Sub z,
> *bar();
> public:
> Nested();
> private:
> };
> Nested y;
> public:
> Nested *foo();
> };
>
> main()
> {
> Goo x;
> }
>
> Goo::Nested::Nested()
> {
> bar();
> }
>
> Goo::Nested::Sub* Goo::Nested::bar()
> {
> }
>
> Goo::Nested::Sub::Sub()
> {
> }
>
>
>
>
>
>
>
>
>



This archive was generated by hypermail 2b28 : Fri Mar 21 2003 - 15:34:46 PST