[comp.lang.c++] implementation of static local variables

ruben@otc.otca.oz (Ruben Gonzalez) (03/14/90)

	The general argument for the existence of local static variables
primarily involves that  of modular cohesiveness.

	In languages which do not support local static variables, any variable
whose value must persist across function invocations must be globally
defined, this destroys modular cohesivness.
The problem arises in C++ with the way in which static local variables
are implemented for non static member functions. At the moment any static local
variable (SLV) belonging to a non static member function is treated as
if it were a normal static member variable of the object of which the
function is a member. Therefore it will be accessed and modified by all
instances of that object. SLVs within member functions are therefore
made redundant by normal static member variables and should not exist.

	There is apparently no way to implement a local variable
within a member function  of an object which persists across
invocations whose scope is limited to that particular instance
of the object. As far as I have been able to asertain the
only way round this is to create a non static member variable,
and to use that. 

	The problem is that modular cohesion is destroyed. Why
should I have to make a variable visible to an entire
object when it is only used by one member function? This
is like having to make a variable in PASCAL  global
because SLVs  are not implemented. The implementation
at the moment for SLVs as mentioned is redundant and at
any rate it transgresses the concept of having
independent instances of an object. Why can't the
implementation of SLVs not be such that their scope is
restricted to  only the instance of the object in which
the owner function occurs. Thus maintaining the
validity of the main argument in favour of the
existence of SLVs. 

	As it stands, it appears to be a blotch on C++s
otherwise impressive implementation.  If for
some reason there is a better way so that I
don't have to violate the most basic rule in
the book about modular programming, or at least
a half decent reason for why it must be so,
please let me know.

	In the Interests of Better Programming.
	Ruben Gonzalez.

marc@dumbcat.UUCP (Marco S Hyman) (03/16/90)

In article <1350@otc.otca.oz> ruben@otc.otca.oz (Ruben Gonzalez) writes:
    
    Why should I have to make a variable visible to an entire
    object when it is only used by one member function?

Call it the pragmatics of implementation.  If the variable is to be kept on
a per instance basis then it must be kept in the struct that defines the
class.  Since the size of the struct must be known by all files that use the
struct all elements of the structure must be defined in the header file.
About the only way around this is some kind of pre-compiled class with other
classes reading some kind of class description file instead of the header.
But that's not C++.

// marc
-- 
// {ames,decwrl,sun}!pacbell!dumbcat!marc
// pacbell!dumbcat!marc@lll-winken.llnl.gov

sakkinen@tukki.jyu.fi (Markku Sakkinen) (03/16/90)

In article <1350@otc.otca.oz> ruben@otc.otca.oz (Ruben Gonzalez) writes:
>
>	The general argument for the existence of local static variables
>primarily involves that  of modular cohesiveness.
> ...
>The problem arises in C++ with the way in which static local variables
>are implemented for non static member functions. At the moment any static local
>variable (SLV) belonging to a non static member function is treated as
>if it were a normal static member variable of the object of which the
                             (should be 'class':)  ^^^^^^
>function is a member. Therefore it will be accessed and modified by all
>instances of that object. SLVs within member functions are therefore
                   ^^^^^^ (should be 'class')
>made redundant by normal static member variables and should not exist.

They are certainly not redundant. The question below that I have
marked '[*]' applies exactly to this distinction.
Unless I am badly mistaken, the visibility of static variables
declared in a member function is restricted to that function
(just like in an ordinary function).

(Even in the rest of the original article, 'object' is always used
when 'class' is meant.)

> ...
>	The problem is that modular cohesion is destroyed. Why
>should I have to make a variable visible to an entire
>object when it is only used by one member function? [*] [...]
> [...]  If for
>some reason there is a better way so that I
>don't have to violate the most basic rule in
>the book about modular programming, or at least
>a half decent reason for why it must be so,
>please let me know.

There is a valid point in the original article, although it also
shows non-understanding of the principles of _object-oriented_
programming. Let's try to clarify a little.

First of all, there is only one instance of each member function
of a class, no matter whether it is "static" or not.
Being static means only that the function can be invoked directly
(without reference to any instance of its class) and that 'this'
is not implicitly defined within the function.
For a data member, "static" means a _class variable_ (in e.g. Smalltalk
vocabulary), while otherwise it is an _instance variable_.
(This is an example of C++ overloading the same syntax with umpteen
subtlely different meanings.)

What Gonzalez is missing in C++ are instance variables that are visible
to one member function only. This would be more sensible if generalised
a little: visible only to some group of member functions. In any case,
the declaration of such instance variables (data members) would belong
to the class definition, _not_ to the member function definition -
otherwise the compiler would not know from a class definition even what
the size of an instance should be!

C++ already has the visibility attributes 'public', 'protected', and 'private'.
Gonzalez's requirement would mean that visibility could be limited even
further from 'private'. The utility would perhaps not be great enough
to justify the added complexity. Further, should some special member
functions such as constructors, destructor and assignment always be
automatically allowed to access "limited" data members?

Fortunately, there appears to be at least one not very inconvenient way
to accomplish the desired effect without modifying C++.
Suppose you would like to allow only the member functions 'zip' and 'zap'
to access the data members 'gold' and 'silver' of the class 'treasury'.
The trick is to define an "auxiliary class", say 'precious', such that
'gold' and 'silver' are _private_ data members of 'precious' and there
is a data member of type 'precious' in 'treasury'. Also declare the functions
'treasury::zip' and 'treasury::zap' to be friends of 'precious'.
That should essentially be it. (The auxiliary class can even be anonymous,
so you spare yourself the invention of one name.)

Apart from C++, there was an approach to different views of the same object
in Edward Sciore's paper "Object specialization". See recent postings
in the comp.object group.

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland
          SAKKINEN@FINJYU.bitnet (alternative network address)

mikem@otc.otca.oz (Mike Mowbray) (03/19/90)

In article <1350@otc.otca.oz>, ruben@otc.otca.oz (Ruben Gonzalez) says:

 > [...] At the moment any static local variable (SLV) belonging to a non
 > static member function is treated as if it were a normal static member
 > variable of the object of which the function is a member. Therefore it
 > will be accessed and modified by all instances of that object.

Eh?? If this is true it's a bug. Example please. Static local variables
*inside member function implementations* shouldn't be visible outside that
function.

 > SLVs within member functions are therefore made redundant by normal
 > static member variables and should not exist.

Static local variables and static member variables are *different* :

	class Foo
	{
		static int  classlocal;  // visible within all member fns
	    public:
		int	show();
		void	blah();
	};

	int Foo::show()
	{
	    static int  funclocal;  // not visible to Foo::blah()

	    return  funclocal = classlocal;
	}


 > There is apparently no way to implement a local variable within a
 > member function of an object which persists across invocations whose
 > scope is limited to that particular instance of the object.

Correct. The "unit" for scoping such things is the class. That's what
data-abstraction and object-oriented programming are all about.

 > As far as I have been able to asertain the only way round this is to
 > create a non static member variable, and to use that.

I venture to suggest that it would better not to try to get around it, but
rather to alter your design to use objects.

 > The problem is that modular cohesion is destroyed. Why should I have
 > to make a variable visible to an entire object when it is only used by
 > one member function?

If this is so, then the selection of classes may be incorrect. You might
try using a smaller class to abstract the functionality of the
"memberfunction-plus-data" in question.

		Mike Mowbray	    ACSnet: mikem@otc.oz
		Network R&D	    UUCP:   {uunet,mcvax}!otc.oz!mikem
		|||| OTC ||	    Phone:  (02) 287-4104
				    Snail:  GPO Box 7000, Sydney, Australia

davidm@uunet.UU.NET (David S. Masterson) (03/19/90)

In article <142@dumbcat.UUCP> marc@dumbcat.UUCP (Marco S Hyman) writes:

   In article <1350@otc.otca.oz> ruben@otc.otca.oz (Ruben Gonzalez) writes:

       Why should I have to make a variable visible to an entire object when
       it is only used by one member function?

   Call it the pragmatics of implementation.  If the variable is to be kept on
   a per instance basis then it must be kept in the struct that defines the
   class.  Since the size of the struct must be known by all files that use
   the struct all elements of the structure must be defined in the header
   file.  About the only way around this is some kind of pre-compiled class
   with other classes reading some kind of class description file instead of
   the header.  But that's not C++.

I think I missed something in this discussion (like the whole original
message), but, given the question above, isn't this the meaning of a "static"
local variable (a variable declared within the scope of only the member
function with a "static" storage class)?  That's the straight C definition?!?
--
===================================================================
David Masterson					Consilium, Inc.
uunet!cimshop!davidm				Mt. View, CA  94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"