Re: [sv-ec] Protection of class types


Subject: Re: [sv-ec] Protection of class types
From: Michael Burns (Michael.Burns@motorola.com)
Date: Mon Mar 24 2003 - 08:32:31 PST


Kevin,

My proposal was to disallow using the "local" keyword to declare
nested classes.

Mike

>> 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 : Mon Mar 24 2003 - 08:39:53 PST