Re: [sv-ec] question about name resolution in classes

From: Neil Korpusik <Neil.Korpusik_at_.....>
Date: Sat Mar 25 2006 - 17:57:12 PST
The notion of class methods being able to directly access variables that are
declared outside of the class goes against the grain of object-oriented
programming (OOP). It is my opinion that class methods should only be able to
access class properties or arguments that are passed to the method. This is
consistent with C++.

One of the concepts of OOP is data encapsulation. Allowing class methods to
reach outside of the class to access variables declared in a module or program
breaks the concept of data encapsulation. Accessing variables in this way
creates the equivalent of a global variable which is shared by all instances of
the class.

At a minimum, this type of variable access is a very poor programming style.
It allows inadvertent access to variables outside of the class when the
intent was to use a class property. This could be a difficult bug to find.

The following is not a valid C++ program. The C++ compiler complains with
"The name i is unusable in c::geti()."

   #include <iostream>
   int main() {
      int i;
   class c {
   public:
      void geti() {
         printf("i=%0d\n", i);  <-- C++ compiler complains
      }
   };
      c  c1;
      i = 69;
      c1.geti();
   }



Gordon Vreugdenhil wrote On 03/23/06 22:27,:
> Fancoise,
> 
> I'd like to make sure that I understand your thinking here -- I
> think that you are suggesting that normal lexical and
> package name binding should occur *before* class hierarchical
> resolution, is that correct?
> 
> In particular, given a simpler example of my example:
> 
>     module child;
>        int i;
>        class base;
>            int i;
>        endclass
>        class derived extends base;
>            function void dump;
>                $display(i);
>            endfunction
>        endclass
>     endmodule
> 
> your view would be that the reference to "i" inside
> derived::dump would refer to child.i and not to
> the property in base.  If the user wanted to refer
> to the property in base, they would have to use
> super.i (or possibly this.i).  Is that a correct
> understanding of your description?
> 
> Gord
> 
> 
> 
> francoise martinolle wrote:
> 
>> 
>>Gordon,
>>
>>That is an interesting sophisticated example where the base class is not
>>known until elaboration.
>>I agree that there are some lexical ways for removing ambiguity in which
>>scope to resolve a
>>symbol (this, super). If we follow the normal verilog name resolution rules,
>>in your example, since there is a child.i, i would resolve to child.i
>>
>>My opinion is that if there was an import p::*, then the parser needs to
>>attempt to resolve
>>the symbol by looking up in the package. The package look up is now part of
>>name resolution
>>as I had pointed out before. 
>>If the user needs to specify that i is a property of the class hierarchy,
>>super.i needs
>>to be used. If the symbol is not resolved at that point (no import and no
>>static i), I would
>>think that in your case we ought to consider 'i' as an oomr which may be
>>resolved at
>>elaboration. We should only consider this last resort because type of the
>>immediate scope
>>containing the symbol 'i' is not known until elaboration and i because it is
>>a simple name
>>needs to be resolved in that scope.
>>That scope is not *complete* until elaboration.
>>This is a new case of oomrs. Usually (with the exceptions of functions and
>>tasks) an oomr
>>consists of more than 1 token separated by '.'
>>
>>In summary, I expect the following:
>>
>>During parsing, normal Verilog name resolution rules (augmented by
>>systemVerilog package look up)
>>apply, 
>>then if the symbol is still undefined and the scope in which it appears is a
>>type which is
>>not known until elaboration, then the symbol is an oomr which is resolved at
>>elaboration when the type
>>is known.
>>
>>Another approach is to avoid the oomr for simple name and require that i be
>>resolved at parsing time.
>>However if super.i is used, allow the oomr to be resolved at elaboration.
>>
>>Francoise
>>    '
>>
>>-----Original Message-----
>>From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of Gordon
>>Vreugdenhil
>>Sent: Thursday, March 23, 2006 6:40 PM
>>To: francoise martinolle
>>Cc: sv-ec@eda.org
>>Subject: Re: [sv-ec] question about name resolution in classes
>>
>>Francoise,
>>
>>This is an area that is quite a bit more interesting than even your example.
>>
>>The basic question is how to align lexical (and package) search rules with
>>class member and property lookup.
>>
>>In the package case (such as yours), since the package is required to exist,
>>the resolution of the base type is required to be known, so I think the
>>intuitive answer is that "i" is the member reference and needs to be
>>resolved as such.  It isn't clear to me however that this is going  to end
>>up being the answer.
>>
>>There are other contexts which are far more difficult since there are
>>separate compilation issues that come into play.
>>
>>Consider:
>>
>>    module child;
>>       parameter type T = int;
>>
>>       int i;
>>       class derived extends T;
>>           function void dump;
>>               $display(i);
>>           endfunction
>>       endclass
>>    endmodule
>>
>>    package p;
>>       class base;
>>           bit b;
>>       endclass
>>    endpackage
>>
>>    module top;
>>       class base;
>>          int i;
>>       endclas
>>
>>       child #(base) c1();
>>       child #(p::base) c2();
>>    endmodule
>>
>>In this scenario, what does "i" mean in class derived?  You can't possibly
>>know what it is or whether it is even lexically resolved to child.i or
>>resolved in the context of the class hierarchy.
>>In my example, the answer changes in the different module instances.
>>
>>Since module child is a valid module for separate compilation there is no
>>way to determine the answer at compilation; elaboration time is the earliest
>>at which this can be resolved.
>>
>>This is complicated by the package import rules.
>>If you didn't have "i" declared in "child" but it was potentially visible,
>>would you do the import and make it actually visible?
>>
>>One reasonable approach to the general problem is to require a "this." or
>>"super." prefix for references to inherited members in at least some
>>situations.
>>
>>I don't think there is any ideal solution to the naming issue since you
>>either have to deal with syntax requirements or have to try to define some
>>reasonable rules for when an implementation is required to know things about
>>the inheritance structure and when the user is required to disambiguate.
>>
>>This is loosely related to the issues with randomize() that Ray and I have
>>been working on a proposal to address.
>>
>>Gord.
>>
>>
>>francoise martinolle wrote:
>>
>>
>>>Supposed I have a base class in a package and I create a derived class 
>>>of that class in a module. I do not import the package but I use the 
>>>package scope syntax to indicate the base class. Does this cause all 
>>>the class item declaration of the BASE class to be visible in the 
>>>derived class?
>>>
>>>I think it should.
>>>
>>>
>>>package p;
>>>class BASE;
>>> rand logic i;
>>>endclass
>>>endpackage
>>>
>>>
>>>module top;
>>>class derived extends p::BASE;
>>>      constraint c1 { i == 1'b1};
>>>endclass
>>>endmodule
>>>
>>
>>
>>--
>>--------------------------------------------------------------------
>>Gordon Vreugdenhil                                503-685-0808
>>Model Technology (Mentor Graphics)                gordonv@model.com
>>
> 
> 

-- 
---------------------------------------------------------------------
Neil Korpusik                                     Tel: 408-720-4852
Senior Staff Engineer                             Fax: 408-720-4850
Frontend Technologies - ASICs & Processors (FTAP)
Sun Microsystems
email: neil.korpusik@sun.com
---------------------------------------------------------------------
Received on Sat Mar 25 17:57:17 2006

This archive was generated by hypermail 2.1.8 : Sat Mar 25 2006 - 17:57:31 PST