Does C# have static local variables like C++?

Z

Zytan

Not sure what you call directly, but this...
...
void sqrval(const int &val)
{
const_cast<int &> (val) = val * val; // cast away const on val}

int main()
{
int x = 22;
sqrval(x);
cout << "x after call: " << x << endl;
return 0;}

prints:
x after call: 484

... is pretty direct for me!

Yes, right. const_cast does exist. But it could't be done on x
itself, only on val. But, it is pretty 'direct' in the case you
shown.

http://msdn2.microsoft.com/en-us/library/ms861539.aspx
"You cannot use the const_cast operator to directly override a
constant variable's constant status."
Name it as you like, the const_cast operator is meant to cast-away const.

Yes. And, of course, there are other ways to do it. Get a pointer to
the same location, and dereference it. The real point is that 100%
prevention is not the issue. I think people think that because const
can be worked around its meaningless.
I didn't say it would be invaluable, it's simply not that valuable as it could be if it was
enforced by the run-time.

Ah. I wasn't thinking how valuable it could be enforced at run-time.
It's valuable enough as-is at compile time.
But as I said previously, the run-time can not enforce it because this would require all
major languages to support const, something which is not feasible as some languages pre-date
.NET.
Yes.

So what's left is support it at the language level, something which is done in C++/CLI, but
this offers nothing more than what you have in C++ , you got even less as the FCL which is
KEY in .NET doesn't supports const , and other .NET languages know nothing about const.

Yes, I was only speaking about the benefits of having C++ type const.
Nothing more.
see: because it's not enforceable on any parameter subsequently passed to a method (think
the FCL, written in C# and C++/CLI), it is not possible to insure the transitive closure on
the constness of the call chain for each parameter.

I haven't claimed it is possible to ensure a const variable remains
unchanged. That has never been the point.

The point is the benefit it brings at compile time. My C++ experience
has shown me this.
Yep, but as I said the CLI is a multilanguage platform, which is much more valuable than
non-enforced constness.

Of course. I didn't say enforced constness was needed. I was
speaking only of the compile time errors that result.

This is the lack of understanding I fought through in the VB groups.
I don't know how to make it clear. const vars cannot be enforced
(unless the runtime does this), and I never claimed this is needed or
required. constness helps the compile stage tell you you're doing
something stupid, where you're giving something access to something it
should have access to, etc. That's where it helps. The fact that you
can cast away const is 100% irrelevant. It is sad that because C#
designers found they couldn't enforce const vars to be unchanging that
they didn't include it, since it's not required. A lock is still
useful even if some people can crack it.
As I said, it's a can of worms, and IMO it makes no sense to open it any further as (IMO) we
won't have it anyway.

Very true.

But, it's good to have an open mind about things and consider
possibilities.

Zytan
 
Z

Zytan

Const is "Godsend"? IMO, on the contrary.

IMO, it is. Once implemented into the source, the compile time errors
forced me to restructure a hierarchy of data passing, since only 1 or
2 functions had access to something they shouldn't. It showed me that
my complicated hierarchy was wrong. It's a high level version of
strict type checking. C#'s enforcing of bool != int, unlike C++, it
great, because it says "hey, you did something wrong". That's what
const does. At compile time. Just like the bool != int error at
compile time. I'll say it again: *at compile time*. There is no way
someone who has not experience const do this can convince me that
const is not a godsend when I have directly experience how it showed
me the errs of my ways. And believe me, this error was far more
significant than using int instead of bool.
And thats why Anders Hejlsberg did not want't to introduce it so widely in
C#.
And after 8 yrs of C/C++, I really do agree with him.

The following is from an interview
(http://www.artima.com/intv/choicesP.html):

"
Anders: ... With respect to const, it's interesting, because we hear that
complaint all the time too: "Why don't you have const?" Implicit in the
question is, "Why don't you have const that is enforced by the runtime?"
That's really what people are asking, although they don't come out and say
it that way.

That is totally, absolutely, completely, NOT the question I am
asking. I could not possibly care about having run time enforcing on
constant vars any less than I do. It's not possible. It's slow. It
marginally brings more benefit than not having run time enforcment.

My point is the C++ style of const. The COMPILE TIME errors that
result from you accidentally changing a const var, or passing a
reference to a function you *think* doesn't change it, but you find
that it does, or after 10 or 20 chained function calls, you see that
one has access to the var that it shouldn't, so you make it const,
which forces the others to be const, etc., until finally you realize
that the original function had no right to be doing what it was doing,
so 'const' tells you you're an idiot, and you fix the hierarchy.
The reason that const works in C++ is because you can cast it away. If you
couldn't cast it away, then your world would suck.

Anders Hejlsberg is a very smart man. His work on Turbo Pascal,
Delphi, and C# is amazing, and that's an understatement. But what he
says here is wrong. He would have a hard time explaning to me how my C
++ const (which I didn't cast away, I didn't need that feature) did
NOT help me solve my major archetectural issue.

Thanks for the interview link.

Zytan
 
W

Willy Denoyette [MVP]

Paul Werkowitz said:
Am Wed, 28 Feb 2007 18:03:08 +0100 schrieb Willy Denoyette [MVP]:
How is it different?

Argh! You know what the difference is!
IMHO it is undisputed good programming style to limit the visibility of an
object to the smallest possible area. If count is meaningful only in the
scope of a function, it should be possible to limit its visibility to
exactly that scope.

Local statics are the means to accomplish that.

Local statics might expose some properties that make them unsuitable for
certain tasks - they are not thread safe, for example (at least in C++).
They are useful in many situations, though. I gave a very simple example, I
can give others if somebody is interested.

[snip]
Because the C# language designers did not see a great value in it?
Well, seems questionable to me. I can see no disadvantage in having them.


Paule


Please, I know the value 'static locals' could bring if I wouldn't have to deal with the
possible disadvantages, like lifetime management and thread safety.
Look at how both VB.NET and C++/CLI (both .NET language members) have implemented 'static
locals' and you'll see what I mean.
VB.NET stores the static in a per application domain heap, so here we know that the variable
goes away when the AD unloads, great, as long as you know that your AD was unloaded and the
"static locals" variables were initialized again.
In VB.NET, a static local is only static when declared in a static (shared in vb) method,
else it's simply a non static instance member, the same initialization protection code is
synthesized by the compiler for no visible reason (this is by design or it's a bug).
VB.NET protects the variable, so that it gets initialized correctly in the presence of
multiple threads, but, still you need to synchronize accesses whenever the function can be
called from multiple threads. This is quite confusing, who's consistently synchronizing
accesses to locals?
C++/CLI doesn't protect the initialization in a thread un-safe way (aka C++) .
C++/CLI stores the static in a process heap, here the variable's lifetime is that of the
process, EEK! this leaks memory when the AD unloads.
Now, what model would you want C# to follow? Whatever, there will always be a trade-off, and
you'll have to answer the question - does the advantage of static locals outweighs the
disadvantages?

Willy.
 
W

Willy Denoyette [MVP]

Zytan said:
Yes, right. const_cast does exist. But it could't be done on x
itself, only on val. But, it is pretty 'direct' in the case you
shown.

http://msdn2.microsoft.com/en-us/library/ms861539.aspx
"You cannot use the const_cast operator to directly override a
constant variable's constant status."

So what? This is not what const_cast is designed for anyway.
Yes. And, of course, there are other ways to do it. Get a pointer to
the same location, and dereference it. The real point is that 100%
prevention is not the issue. I think people think that because const
can be worked around its meaningless.

This is NOT my opinion, I know the value of const correctness in C++, but heck this is a
different play field an C# is not the only player.

Ah. I wasn't thinking how valuable it could be enforced at run-time.
It's valuable enough as-is at compile time.

True, but as I said it's too late, I tried very hard to write const correct code using
C++/CLI and finaly gave up because all I had to do was const_cast object references passed
as parameters to the FCL methods to finally fnd out that a const_cast is not permitted on
all reference types (bummer).
try this for instance:
void Foo(const C^ c)
{
...
Console::WriteLine(c);

It fails because the FCL is const incorrect, but actually, it's the FCL which rules .NET,
not the languages.
Yes, I was only speaking about the benefits of having C++ type const.
Nothing more.

Well C++ is still alive and kicking :)).
I haven't claimed it is possible to ensure a const variable remains
unchanged. That has never been the point.

The point is the benefit it brings at compile time. My C++ experience
has shown me this.
True, but this is not C++, it's no longer the language who dictates the rules.
Of course. I didn't say enforced constness was needed. I was
speaking only of the compile time errors that result.

This is the lack of understanding I fought through in the VB groups.
I don't know how to make it clear. const vars cannot be enforced
(unless the runtime does this), and I never claimed this is needed or
required. constness helps the compile stage tell you you're doing
something stupid, where you're giving something access to something it
should have access to, etc. That's where it helps. The fact that you
can cast away const is 100% irrelevant. It is sad that because C#
designers found they couldn't enforce const vars to be unchanging that
they didn't include it, since it's not required. A lock is still
useful even if some people can crack it.


Very true.

But, it's good to have an open mind about things and consider
possibilities.

Wholeheartedly agreeing.

Willy.
 
J

Jon Skeet [C# MVP]

Zytan said:
Well, if you replace them with class vars, then that's "stupid"

Why? Replacing a static local variable with an instance/static variable
in the enclosing type, but never using it, will give the exact same
semantics as before - including the lack of thread safety.

On the other hand, it'll make it obvious that it's part of the state of
the type/instance, which is hidden by it being a static local variable.
That's one of my main beefs with static local variables - they're state
which is hard to spot.
 
Z

Zytan

Well, if you replace them with class vars, then that's "stupid"
Why? Replacing a static local variable with an instance/static variable
in the enclosing type, but never using it, will give the exact same
semantics as before - including the lack of thread safety.

Because methods other than the single method that static local would
be in can use it, thus it is opening up its visibility to more than it
needs to.
On the other hand, it'll make it obvious that it's part of the state of
the type/instance, which is hidden by it being a static local variable.
That's one of my main beefs with static local variables - they're state
which is hard to spot.

Now that's a good reason static locals are bad. I get it. State. A
good way of looking at an object / class.

Thanks.

Zytan
 
J

Jon Skeet [C# MVP]

Zytan said:
Because methods other than the single method that static local would
be in can use it, thus it is opening up its visibility to more than it
needs to.

Yes, and that's the only downside, as far as I can see. It definitely
*is* a downside, but then so is hiding the fact that you've got state.
Now that's a good reason static locals are bad. I get it. State. A
good way of looking at an object / class.

:)
 
P

Peter Duniho

[...]
How could you ever assume that f will be called directly in f? My
original
example does not have such an assumption. To be honest: In a real world
application, f might call h, which might call g, which invokes a delegate
that sends a Windows-message which leads to another call of f

Fine. Then just put the "static" variable outside of the function, as
suggested elsewhere. At least that way, it is clear to anyone reading the
code where the data is stored and what its lifetime is.
And these are?

Well, I proposed two, and others have provided additional methods. You
don't have to have a static local variable in order to track recursion
level.
Your example above tries to show how we can solve the given task of
"recursion detection". It can work in certain situations (e.g. recursion
does not go through Windows messages & message pump). It has the
disadvantage that all functions in the chain ( f, g, h, delegate etc.)
now must have an additional parameter.

How is that a significant disadvantage?
What if h is used in another context,
where recursion is not an issue? what would the caller of h provide for
the value?

In a non-recursive context, you would have to use some other solution. So
what?
You impose additional complexity on h and all clients of h simply
because f has some problem? No, sire.

There is no "additional complexity". There is simply "different
complexity". How is keeping a static local variable, which you increment
upon function entry and decrement upon exit, not complex in and of
itself? Other solutions are not more complex...they are just different.
See the problem? The recursion-checking-value has absolutely no meaning
for h or anybody else except f. And thats why it should be confined to f.

But a static local variable isn't truly confined to f. The problem is
that it only *looks* like it is confined to f. The only confinement is in
visibility, and because it is not confined in other ways, it is possible
for a programmer to misunderstand what is going on and create bugs.
Could you please elaborate a little why use of static variables is bad
coding practice? I can't see this.

Well, for one in languages where a local static variable essentially
creates a global variable, you are violating the basic tenet to minimize
global variables. Global variables exist for the entire lifetime of an
application; even when they are not being used, they take up space.
Taking up space you aren't using is wasteful and is apoor programming
practice.

Others have explained how in particular versions of VB, static local
variables have less-than-intuitive behavior. For example, the possibility
of a static local being reinitialized during execution.

In C#, one problem your static local has is that if an exception occurs
within the routine, if there is no exception handler in that routine, then
the recursion level as tracked by your static local will be incorrect.
Alternatively, you have to add an exception handler in the routine, which
increases complexity (something you apparently are against).

This is not a complete enumeration...just a taste so you can get a feel
for why one should avoid static locals in the first place (even when a
language allows them).
Shudder. Then why do we need "private" at all?

I'm not saying it's a great solution. I'm just saying it's not any worse
than the already-bad practice of using static locals.
Well, depends. I gave a very basic example for their use, and I can give
some more, which are more elaborate. Of course, if you never used them
you might not miss them.

Frankly, in my past I have used static locals WAY more than I should
have. They can be very convenient. But they can also result in
hard-to-maintain code, introduce subtle bugs, and waste valuable memory
space. I have learned through hard experience that when I think I need a
static local, I really need something else (especially when programming in
an OOP environment). I used to use them a lot, and I don't miss them at
all today.
But from a greater distance the picture is different.
Again, when you think you don't need local statics: please give a
suitable implementation of the recursion detection problem.

I suspect your definition of "suitable" will restrict possible examples to
those that behave in *exactly* the way a static local would. Given that,
I have to admit that it's unlikely anyone could come up with something you
consider "suitable". However, in reality you don't need something that
works *exactly* the way a static local would. You just need something
that solves the problem at hand (knowing how many levels of recursion
you've called the function), and there are a number of alternatives to a
static local in that case (as has already been pointed out). You
obviously disagree that they are "suitable", but so far you've made no
compelling argument that they are any worse than your proposed use of a
static local.
Harder to maintain? Not really.

Yes, really. A static local makes it more difficult for the original
coder or someone else coming along to deal with the code to fully
understand what happens when a function is executed. It can lead to new
bugs (as new code is added that deals with the static local improperly) or
hide the correct resolution of existing bugs. These are qualities that
are very much barriers to maintainability.
Side effects? You should give an example,
how a static local variable would allow for any side effect.

Please read the text to which you intend to respond. In particular, I
never once wrote that static locals cause side effects.

However, one major reason side effects are bad is that it makes it a lot
harder to understand what a function does. The most maintainable function
is one that has some simple input, and creates some simple output. Side
effects break this paradigm. Likewise, a static local creates a situation
where a function may not do the exact same thing, even when given the
exact same output. Again, this breaks the "simple input, simple output"
paradigm.

Static locals do not *cause* or *allow* for any side effects. However,
they create maintainability and code-correctness problems that are very
similar to those created by side effects. Thus "kissing cousins" (perhaps
English is not your native language..."kissing cousins" is an English
idiom that refers to two things that are significantly different from each
other, and yet remain closely related).
Yes. But same argumentation holds for statics at class level. Non-statics
are initialized in the ctor, statics are not. Same thing, different
place.

Incorrect. A static at the class level has a very well-defined
initialization paradigm. As has already been explained elsewhere, when
and where a static local is initialized, and how many times during a
specific execution, is not so simple.

That said, you do have a valid point with respect to the disparity between
static class members and per-instance ones. Which is why a) one should
only use static class members when the data is truly class-specific and
only makes sense as a static member, and b) all static class members
should be declared together in a very clearly marked area. One does not
have this opportunity with static locals...they must appear within each
function in which they are used, and it's surprisingly easy to gloss over
the "static" in the declaration and not realize that one is dealing with a
static variable.
Well, if the programmer does not know the rulez, I can't help.

Huh? Previously you sarcastically argued that one should just abandon the
whole concept of data hiding. And yet now, you argue that the programmer
should just "know the rules". Which is it? Do you want the language to
assist in writing better code, or don't you?
My advice
then is simply not to use language features you don't fully understand. A
much more complex topic are delegates or generics ot anonymous functions
-
do you suggest to delete them from the language, too?

Complexity of the feature is not the problem. The ease of which a
language feature can lead to unintended bugs is. Your other examples do
not fit in that category the same way that static locals do.
[...]
Well, then give an implementation of the "recursion detection problem" in
C# that is acceptable.

How many times should alternate implementations be posted before you
recognize one as such?

Pete
 
P

Peter Duniho

I do. You letting it be visible to *far* more than it should be
visible to. The difference is just as grand relatively speaking as
changing it from class scope to global scope.

I don't see that as a significant difference. It's a difference, to be
sure. But compared to the larger problem of having the "static local" in
the first place, it's very minor.
What good coding practice is being broken? I don't follow.

I hope that there has been ample discussion of the problems already. From
later portions of your post, it seems so, and if not my other reply to
Paul should suffice.
Also, evem if it is breaking a law of good coding practice (which I
can't see ATM), it doesn't mean you should further break another law.

It just depends on the severity of the law. You shouldn't have state that
is static to a function in the first place. But if you are going to
insist on doing that, it is a relatively minor transgression to make that
state visible more widely than it should be. And of course, making the
state visible more widely than it should be may well increase a coder's
discomfort to the point where they realize that state static to a function
is a bad idea in the first place.
[...] You can't claim the
rightiousness of good coding practices forced by the language are a
good thing, and then turn 180 and say 'well, that's ok that the
language doesn't enforce that, because you can enforce it yourself'.
It's all the same soup.

See above. I'm not saying that either practice is good. Simply that one
has a greater hazard than the other. A visibility problem just isn't that
big of a deal compared to a static local.
[...]
After all, C# wasn't meant to run at speeds with C, so the
fact that local statics can improve speed (by negating the need of
parameter passing) is reduced. Good coding practices is a much higher
concern and C# does a great job.

Well, the relative value of performance versus correct code is certainly
one thing to think about. However, I'd also argue that there is very
little evidence that parameter passing turns out to be a significant
factor in typical code performance in the first place. Where it is, in
those rare cases there are solutions other than static locals (fact is,
OOP goes a long way to preventing this sort of problem in the first place,
by allowing much state that is really specific to an object instance to be
stored with the object).
[...]
True. Note that static c'tors are initialized in the same manner, so
the issues above still hold true for them. But, the issues are *well*
worth having static c'tors!

One of the biggest values of static class members and constructors is to
allow a class to exist when there is no real concept of an "instance".
That is, one can always make a class non-static, but doing so requires the
needless allocation of memory, just to create a pointer to which one can
refer. If the class doesn't actually maintain any state, why force a
programmer to create state for it?

Less commonly one might have data that is shared amongst all class
instances. This is another good example of a place where static class
members are useful. But note that in that case, there is explicitly some
sharing going on. This isn't true in the case of a static local
variable...inherently, data in a static local is not shared (that is, it's
not meant to be shared...multi-threading can create situations in which
it's shared unintentionally, which as mentioned before is one of the
several reasons static locals can be hazardous to good, correct code).

I don't really feel that the issues surrounding static classes and static
class members are the same as those around static locals. They play very
different roles in a program.
Well, if you replace them with class vars, then that's "stupid" (and
watch it, as smart as you are, you mentioned this alternative, so if I
am right that it is not a proper alternative, C#'s limitations just
made you suggest 'bad code').

That is right. I'm not suggesting that using a class member (static or
otherwise) is necessarily a *good* idea. It's just a
slightly-less-harmful way to implement the potentially harmful behavior a
static local gives you.
If you replace them with parameter
passing, you get slower code, but that's not "stupid", although some
people may complain about the speed, but then again, C# wasn't meant
for speed, so it's ok. The benefit of good code, the purpose of C#,
far outweights the slower speed of parameter passing, so they made the
right choice.

And I will even agree with Paul that there are situations in which
parameter passing doesn't necessarily work. In a convenient way, that
is...after all, if you have state you want to maintain for the function,
you can always insist that all functions within the call stack be aware
of, and pass down, that state. That's certainly a "safer" mechanism than
static locals, since it makes it obvious what is going on. And of course,
may encourage the programmer to handle the intended behavior in a cleaner,
more appropriate manner in the first place.
I still miss them, though.

Not me. I learned my lesson and stopped using static locals even in
C++ years ago. Their absence in C# hasn't mattered to me at all.

Pete
 
Z

Zytan

I still miss them, though.
Not me. I learned my lesson and stopped using static locals even in
C++ years ago. Their absence in C# hasn't mattered to me at all.

I think I only ever used them for temporary debugging purposes (and
recursive counting like Paul mentioned), so I just miss my quick
debugging tool that I used to have. But, I'll get around it, I'm
sure.

Zytan
 
P

Paul Werkowitz

Am Thu, 1 Mar 2007 19:54:38 +0100 schrieb Willy Denoyette [MVP]:
Please, I know the value 'static locals' could bring if I wouldn't have to deal with the
possible disadvantages, like lifetime management and thread safety.
Look at how both VB.NET and C++/CLI (both .NET language members) have implemented 'static
locals' and you'll see what I mean.
VB.NET stores the static in a per application domain heap, so here we know that the variable
goes away when the AD unloads, great, as long as you know that your AD was unloaded and the
"static locals" variables were initialized again.
In VB.NET, a static local is only static when declared in a static (shared in vb) method,
else it's simply a non static instance member, the same initialization protection code is
synthesized by the compiler for no visible reason (this is by design or it's a bug).
VB.NET protects the variable, so that it gets initialized correctly in the presence of
multiple threads, but, still you need to synchronize accesses whenever the function can be
called from multiple threads. This is quite confusing, who's consistently synchronizing
accesses to locals?
C++/CLI doesn't protect the initialization in a thread un-safe way (aka C++) .
C++/CLI stores the static in a process heap, here the variable's lifetime is that of the
process, EEK! this leaks memory when the AD unloads.
Now, what model would you want C# to follow? Whatever, there will always be a trade-off, and
you'll have to answer the question - does the advantage of static locals outweighs the
disadvantages?

Hello Willy,

tnx for that elaboration.

Of course, these are exactly the questions one has to answer when one wants
to implement the feature. My question is: why can't these questions be
answered the same way they have alredy been answered for statics at class
scope?

Isn't it simply a matter of confining the visibility of a - otherwise
"normal" static - to function scope? Memory layout, lifetime questions etc.
could remain unchanged.

Paule
 
P

Paul Werkowitz

Am Fri, 02 Mar 2007 14:16:30 +0800 schrieb Peter Duniho:
[...]
How could you ever assume that f will be called directly in f? My
original
example does not have such an assumption. To be honest: In a real world
application, f might call h, which might call g, which invokes a delegate
that sends a Windows-message which leads to another call of f

Fine. Then just put the "static" variable outside of the function, as
suggested elsewhere. At least that way, it is clear to anyone reading the
code where the data is stored and what its lifetime is.

Yes, that is possible. Whether it is good or better than local statics
needs to be seen. I just wanted to point out that passing another argument
often is not possible. If the situation is easy, you usualy don't need any
additional means to find th problem. In larger apps there are so many
functions... and suddenly f gets called again from a call within f.

Besides of that - even if it was possible, adding arguments to funtions
that don't use them and don't know nothing of them seems no good practice
to me. All of the functions simply would pass the argument to the functions
they call. The value does not have any meaning to them. It has only meaning
to f. I remember the day when we did not have exception handling. We passed
result state up to the calling function, and then again up to the next
level - until some caller handled them. Luckily this is not necessary any
more.

This all is only a nuisance - it clutters code and is unneccesary work, but
not really bad, only silly. But there are also severe conceptional
problems, too. For example, what happens if you want to use h yourself?
What do you tell your client to pass for that additional parameter? You
impose complexity on h and on all callers of h, although they have nothing
to do with the recursion problem of f. You sure know the principle of
locality, which is broken here.

(I know, you can write another overload of h without parameters and call
the modified h.... - yes, this moves the problems out of sight for h's
clients but the problems remain.)

Well, I proposed two, and others have provided additional methods. You
don't have to have a static local variable in order to track recursion
level.
You are right - but this is not the question. You always can use
alternative ways to accomplish something. I know a guy that keeps telling
me that Cobol is everything a serious programmer needs (no joke) - and,
he's right. Assembler would be equally possible.

It's not so much a question whether "there are alternative ways" but more
"what properties do these alternative ways have compared to local statics".
For example, I gave reason why additional parameters - as you suggested -
are not an option for me. I consider the disadvantages for my code as too
much. It it were possible at all.

[snip]
There is no "additional complexity". There is simply "different
complexity". How is keeping a static local variable, which you increment
upon function entry and decrement upon exit, not complex in and of
itself? Other solutions are not more complex...they are just different.

A valid argument. I answered in the paragraph above. For example. clients
of h have to deal with complexity which does not belong to their domain.
That kind of complexity I judge more severe that that of local statics.


What leaves the other solution that uses statics, too. Whether you use a
static at class scope or factor it out to another (static) class makes no
difference at all. For me, its not so much of a difference where that
static is located. The much bigger difference is that between instance and
static data. A programer simply *has* to understand the difference, period.
Yes, your kissin cousins are there...



But a static local variable isn't truly confined to f. The problem is
that it only *looks* like it is confined to f. The only confinement is in
visibility, and because it is not confined in other ways, it is possible
for a programmer to misunderstand what is going on and create bugs.
You probably mean initialization probs, and threading issues. Yes, the
unloading/relaoding of an AD re-initializes local statics in VB. Maybe they
sell it as a feature, IMHO its wrong.

What a programmer is interested in, is visibility. And no side effects, of
course. If local statics were implemented like class statics except
visibility, I canÄt see any problems.
Well, for one in languages where a local static variable essentially
creates a global variable, you are violating the basic tenet to minimize
global variables. Global variables exist for the entire lifetime of an
application; even when they are not being used, they take up space.
Taking up space you aren't using is wasteful and is apoor programming
practice.

I don't agree with the tenet that globals are bad. Especially when movin
from C to C++ for example, they tend to be heavily overused. But it is as
with any language feature: its not the feature that is bad, it is the
improper use. Don't use globals when you don't have to - but use them when
its appropriate. Look at some arbitrary code and look for static classes
with data members.
Secondly, globals can be null, too. If space was an issue, you can
implement some lifetime management, e.g. with factories and managers. But
since an empty app uses 30 MB of memory on my machine, space mosty is not
an issue. And OS can swap out pages.

And, my local static simply is an int. When we talk about memory, the
additional parameter you suggest cost much more. Not to forget the
additional CPU load (of my dual core Intel).




Others have explained how in particular versions of VB, static local
variables have less-than-intuitive behavior. For example, the possibility
of a static local being reinitialized during execution.

Ack. Bad!
In C#, one problem your static local has is that if an exception occurs
within the routine, if there is no exception handler in that routine, then
the recursion level as tracked by your static local will be incorrect.
Alternatively, you have to add an exception handler in the routine, which
increases complexity (something you apparently are against).

Absolutely right. If exeption safety is an issue, more work is necessary.
Unfortunately .NET has no deterministic destruction, therefore we cannot
program janitors as elegantly as in C++, but one can use using-clause.


[parts snipped)
I suspect your definition of "suitable" will restrict possible examples to
those that behave in *exactly* the way a static local would. Given that,
I have to admit that it's unlikely anyone could come up with something you
consider "suitable". However, in reality you don't need something that
works *exactly* the way a static local would. You just need something
that solves the problem at hand (knowing how many levels of recursion
you've called the function), and there are a number of alternatives to a
static local in that case (as has already been pointed out). You
obviously disagree that they are "suitable", but so far you've made no
compelling argument that they are any worse than your proposed use of a
static local.

I hope you can agree that we must look at the advantages and disadvantages
of the alternatives. I have brought arguments that show the problems of the
sugested alternatives. You have brought your arguments why local statics
are no good. Everybody can make up his mind now.

((I have to go now, and hope I can write something to the rest of the
arrticle later))

Paule
 
Z

Zytan

I remember the day when we did not have exception handling. We passed
result state up to the calling function, and then again up to the next
level - until some caller handled them. Luckily this is not necessary any
more.

Some of us still do that. Exception handling can hide where code
direction can change (say, if you didn't know a function you called
could throw an exception). It's a valid argument, especially when
using libraries NOT designed from the ground up around OOP (say, C/C+
+, or VB6 or earlier).
This all is only a nuisance - it clutters code and is unneccesary work, but
not really bad, only silly.

Clutter, yes. Silly? not any more so than code branching even though
there's no explicit code telling it to do so (exception handling).
Each has their benefits. I think they are about equal, personally.

Zytan
 
J

Jon Skeet [C# MVP]

What leaves the other solution that uses statics, too. Whether you use a
static at class scope or factor it out to another (static) class makes no
difference at all.

There is a *big* difference in terms of readability.

I can glance down the code of a class and ignore all methods, and thus
see all the state, both of the type and of any instances. That's not
true if state of the type/instance can be effectively hidden inside a
method.
 
W

Willy Denoyette [MVP]

Jon Skeet said:
There is a *big* difference in terms of readability.

I can glance down the code of a class and ignore all methods, and thus
see all the state, both of the type and of any instances. That's not
true if state of the type/instance can be effectively hidden inside a
method.

Agreed, the "static" in a method might attract your attention, however, like it's done in
VB.NET, where the static becomes instance state when declared in a non static method,
completely blurs readability.

Willy.
 
P

Peter Duniho

I think I only ever used them for temporary debugging purposes (and
recursive counting like Paul mentioned), so I just miss my quick
debugging tool that I used to have. But, I'll get around it, I'm
sure.

Well, for "temporary debugging purposes", pretty much anything goes
anyway. In that case, there is even less validity in objecting to making
the static local a member within the class (static or otherwise, depending
on your needs).

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top