Subject: Re: [sv-ec] Protection of class types
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Fri Mar 21 2003 - 10:16:44 PST
> 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 - 10:18:18 PST