Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

4 views
Skip to first unread message

Zytan

unread,
Feb 27, 2007, 3:33:49 PM2/27/07
to
I see that static is more restricted in C# than in C++. It appears
usable only on classes and methods, and data members, but cannot be
created within a method itself. Surely this is possible in C# in some
way? Or maybe no, because it is similar to a global variable (with its
scope restricted) which C# is dead against?

Zytan

Mattias Sjögren

unread,
Feb 27, 2007, 3:44:53 PM2/27/07
to

>Surely this is possible in C# in some way?

Nope, you have to make it a class member instead.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Jon Skeet [C# MVP]

unread,
Feb 27, 2007, 3:52:54 PM2/27/07
to

No - methods only have "temporary" storage, and types/instances have
"longer term" storage. I've found that to lead to better encapsulation.
If you find methods which need state which isn't logically part of the
state of the object, you might consider moving the method to a
different class.

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Zytan

unread,
Feb 27, 2007, 4:01:26 PM2/27/07
to
> Nope, you have to make it a class member instead.

Ok, thanks, Mattias

Zytan

Zytan

unread,
Feb 27, 2007, 4:02:52 PM2/27/07
to
> No - methods only have "temporary" storage, and types/instances have
> "longer term" storage. I've found that to lead to better encapsulation.

Yes, I can see that.

> If you find methods which need state which isn't logically part of the
> state of the object, you might consider moving the method to a
> different class.

I was just using it for testing some code. In practice, I don't find
much use for static vars, but they are nice to throw something
together really quick. But i respect c#'s attempt to keep things
proper.

Zytan

Paul Werkowitz

unread,
Feb 27, 2007, 7:18:55 PM2/27/07
to
Am Tue, 27 Feb 2007 20:52:54 -0000 schrieb Jon Skeet [C# MVP]:

> Zytan <zytanl...@yahoo.com> wrote:
>> I see that static is more restricted in C# than in C++. It appears
>> usable only on classes and methods, and data members, but cannot be
>> created within a method itself. Surely this is possible in C# in some
>> way? Or maybe no, because it is similar to a global variable (with its
>> scope restricted) which C# is dead against?
>
> No - methods only have "temporary" storage, and types/instances have
> "longer term" storage. I've found that to lead to better encapsulation.
> If you find methods which need state which isn't logically part of the
> state of the object, you might consider moving the method to a
> different class.

Now, how would you then write something like this in C#?

void f()
{
static int count;
if ( count > 0 )
Debug.Writeline( "recursion level" + count.ToString() );
count++;

// -- the internals of f

count--
}

IMHO, count is only interesting within the scope of f, and therefore should
be defined in f, and nowhere else. But C# forces me to define such
variables at class level, which is stupid.

(OK, its only a minor nuisance, and other things are much worse. But
sometimes I wonder how language designers come to their results).

My 2 cents...
Paule


Zytan

unread,
Feb 27, 2007, 8:27:10 PM2/27/07
to
> Now, how would you then write something like this in C#?
>
> void f()
> {
> static int count;
> if ( count > 0 )
> Debug.Writeline( "recursion level" + count.ToString() );
> count++;
>
> // -- the internals of f
>
> count--
> }
>
> IMHO, count is only interesting within the scope of f, and therefore should
> be defined in f, and nowhere else. But C# forces me to define such
> variables at class level, which is stupid.

Paule, you raise an interesting point. Normally, I only need the
above for quick testing code, not for production code. So, maybe the
designers thought that anything needing a C++ static local variable is
bad. But, like you said, it's only visible inside the function. But,
of course, via pass by reference, anything can be made visible to
anything.

Certainly the fact that you must declare it at the class level is
WORSE than at the method level, I agree.

Zytan

debipra...@gmail.com

unread,
Feb 27, 2007, 10:50:59 PM2/27/07
to
On Feb 28, 5:18 am, Paul Werkowitz <newsgro...@primaprogramm.de>
wrote:

> Am Tue, 27 Feb 2007 20:52:54 -0000 schrieb Jon Skeet [C#MVP]:
>
> > Zytan <zytanlith...@yahoo.com> wrote:
> >> I see that static is more restricted inC#than in C++. It appears

> >> usable only on classes and methods, and data members, but cannot be
> >> created within a method itself. Surely this is possible inC#in some

> >> way? Or maybe no, because it is similar to a global variable (with its
> >> scope restricted) whichC#is dead against?

>
> > No - methods only have "temporary" storage, and types/instances have
> > "longer term" storage. I've found that to lead to better encapsulation.
> > If you find methods which need state which isn't logically part of the
> > state of the object, you might consider moving the method to a
> > different class.
>
> Now, how would you then write something like this inC#?
>
> void f()
> {
> static int count;
> if ( count > 0 )
> Debug.Writeline( "recursion level" + count.ToString() );
> count++;
>
> // -- the internals of f
>
> count--
> }
>
> IMHO, count is only interesting within the scope of f, and therefore should
> be defined in f, and nowhere else. ButC#forces me to define such

> variables at class level, which is stupid.
>
> (OK, its only a minor nuisance, and other things are much worse. But
> sometimes I wonder how language designers come to their results).
>
> My 2 cents...
> Paule

Some where I read (may be "FAQ in C++"), even in C++ this kind of
local static variable is not safe for multi threaded applications. So,
better use functionoid.
Debi

William Stacey [C# MVP]

unread,
Feb 28, 2007, 12:45:17 AM2/28/07
to
| Now, how would you then write something like this in C#?
|
| void f()
| {
| static int count;
| if ( count > 0 )
| Debug.Writeline( "recursion level" + count.ToString() );
| count++;
|
| // -- the internals of f
|
| count--
| }

IMO, if f() is not using any class state, then the method should probably be
a static anyway. In which case "count" would be a static member var.
Moreover, I normally find I end up wanting "count" in class scope anyway as
many times you end up wanting to enumerate it for debug, statistics, or
other flow control in other parts of the class. I have wrote and read lots
of classes, and I never really come up with much need for local static
scope. I can think of one time similar to above, but the fix is easy and
probably not worth the change to the language. However, if I had to bet, I
would guess they add it at some point.

--
William Stacey [C# MVP]
PCR concurrency library: www.codeplex.com/pcr
PSH Scripts Project www.codeplex.com/psobject

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 3:34:50 AM2/28/07
to
"Paul Werkowitz" <newsg...@primaprogramm.de> wrote in message
news:1iv5ju91fmq9a$.124h1uugqvv2f$.dlg@40tude.net...


count has no function 'scope', it's a static after all, it has function 'visibility'.

Willy.


Chris Nahr

unread,
Feb 28, 2007, 3:59:25 AM2/28/07
to
Minor amendment to the other replies: C# does have one special case
of local statics, namely constants of value types.

int Func(int y) {
const int x = 5 * 6;
return x * y;
}

This function is legal. The C# compiler will precompute x and embed
it as a literal constant in the instruction stream.
--
http://www.kynosarges.de

Paul Werkowitz

unread,
Feb 28, 2007, 11:37:32 AM2/28/07
to
Am Wed, 28 Feb 2007 09:34:50 +0100 schrieb Willy Denoyette [MVP]:

>>
>> IMHO, count is only interesting within the scope of f, and therefore should
>> be defined in f, and nowhere else. But C# forces me to define such
>> variables at class level, which is stupid.
>>

>

> count has no function 'scope', it's a static after all, it has function 'visibility'.
>
> Willy.

Hello Willy,
I did not claim that count has "function scope". In fact, I did not say
anything about the scope of count at all.

I said that count is interesting withing the scope of f only, which is a
different thing.

And, BTW, my question is still unanswered: How do you implement the given
task in C#?

(Of course I know the answer - but it is worse) Maybe someone can enlighten
me why local statics are not in the language.


Paule.

Paul Werkowitz

unread,
Feb 28, 2007, 11:47:47 AM2/28/07
to
Am Wed, 28 Feb 2007 00:45:17 -0500 schrieb William Stacey [C# MVP]:

>| Now, how would you then write something like this in C#?
>|
>| void f()
>| {
>| static int count;
>| if ( count > 0 )
>| Debug.Writeline( "recursion level" + count.ToString() );
>| count++;
>|
>| // -- the internals of f
>|
>| count--
>| }
>
> IMO, if f() is not using any class state, then the method should probably be
> a static anyway. In which case "count" would be a static member var.

That's how you have to do it in C# (but not in other languages, e.g. C++).
In C# you have to write

void f()
{


if ( count > 0 )
Debug.Writeline( "recursion level" + count.ToString() );
count++;

// -- the internals of f

count--
}

static int count;

which, IMHO, is clearly inferior.


> Moreover, I normally find I end up wanting "count" in class scope anyway as
> many times you end up wanting to enumerate it for debug, statistics, or
> other flow control in other parts of the class. I have wrote and read lots
> of classes, and I never really come up with much need for local static
> scope.

If it's not appropriate, then simply don't use static locals. I gave an
example where it would be nice. Many other situations come to mind.


>I can think of one time similar to above, but the fix is easy and
> probably not worth the change to the language. However, if I had to bet, I
> would guess they add it at some point.

It would be a non-breaking change, and could have been added with V3. The
fact that nobody complains sheds some light on peoples mindsets. Of course
you can circumvent it - like nearly everything. If you hadn't local
variables at all, you could fix that in the same way, too.....

My 2 cents...
Paule

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 12:03:08 PM2/28/07
to
"Paul Werkowitz" <newsg...@primaprogramm.de> wrote in message
news:13lehacnkh3q2$.1uskckss7any.dlg@40tude.net...

> Am Wed, 28 Feb 2007 09:34:50 +0100 schrieb Willy Denoyette [MVP]:
>
>>>
>>> IMHO, count is only interesting within the scope of f, and therefore should
>>> be defined in f, and nowhere else. But C# forces me to define such
>>> variables at class level, which is stupid.
>>>
>
>>
>> count has no function 'scope', it's a static after all, it has function 'visibility'.
>>
>> Willy.
>
> Hello Willy,
> I did not claim that count has "function scope". In fact, I did not say
> anything about the scope of count at all.
>

> I said that count is interesting withing the scope of f only, which is a
> different thing.
>

How is it different?
If this was possible in C#, like it is in VB.NET, then the scope would still be the scope of
a "static" in the CLR/IL, which is "Application Domain scope", the *visibility* however
could be that of f().

> And, BTW, my question is still unanswered: How do you implement the given
> task in C#?
>

You can't in C#, VB.NET allows you to "declare" a local static, but this is simply
syntactic sugar, the static still becomes a *type* variable (NOT an instance nor a local
variable) , and the compiler limits its *visibility* to the declaring function only.


> (Of course I know the answer - but it is worse) Maybe someone can enlighten
> me why local statics are not in the language.

Because the C# language designers did not see a great value in it?


Willy.

Zytan

unread,
Feb 28, 2007, 12:13:02 PM2/28/07
to
> count has no function 'scope', it's a static after all, it has function 'visibility'.

I thought scope = visibility.

http://en.wikipedia.org/wiki/Variable#Scope_and_extent
"The scope of a variable is the portion of the program code for which
the variable's name has meaning and for which the variable is said to
be "visible"."

Zytan

Zytan

unread,
Feb 28, 2007, 12:17:04 PM2/28/07
to

I noticed that I can't do this:
const int x = MyMethod();
because MyMethod() isn't constant.

But, what I want to do is that after x is assigned, not allow it to
change. C# doesn't allow that. I wonder why.

Zytan


Bruce Wood

unread,
Feb 28, 2007, 1:16:20 PM2/28/07
to
On Feb 28, 8:47 am, Paul Werkowitz <newsgro...@primaprogramm.de>
wrote:

> It would be a non-breaking change, and could have been added with V3. The
> fact that nobody complains sheds some light on peoples mindsets. Of course
> you can circumvent it - like nearly everything. If you hadn't local
> variables at all, you could fix that in the same way, too.....

Oh, please. You cannot seriously compare the presence / absence of
local variables with the presence / lack of static variables local to
methods. They're not even in the same ballpark.

Here's a mindset for you: every feature that's added to C# has two
sides to it: the functionality / flexibility that it adds to the
language, and its potential for abuse. You yourself admit that this is
simply a "nice to have" that would make a few scenarios more elegant.
I agree with you.

The downside is the potential for abuse: the ability to create nasty
little functions that do something different "sometimes" because they
save state across calls.

For me, the question is not, "Why didn't they include this feature
that I would find useful?" but "Did they omit this feature because
it's not really all that useful and makes it easy to write junk code?"

C++ is an expert's language. It has many features that in an expert's
hands can result in more elegant code, but in the hands of a novice
become traps and pitfalls. C# is more workmanlike, IMHO. It's targeted
not at experts but at the average Joe Programmer, so the feature set
is different.

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 1:27:25 PM2/28/07
to
"Zytan" <zytanl...@yahoo.com> wrote in message
news:1172682781....@m58g2000cwm.googlegroups.com...

True, visibility = lexical scope. What i really was trying to say was that the extend (or
lifetime) was different.
Consider this small sample in vb.net:

Public Class C
Public Sub Foo(item As Integer)
Static staticLocal As Integer = -1
staticLocal = item
End Sub
End Class

here "staticLocal " is declared as a static local, that means that "staticLocal " lexical
scope is equal to it's active binding in program code, that is from the beginning of Foo
till Foo returns, which is also it's visibility as far as Foo is concerned.
Now, the variable itself is a static (and really a type variable), as such has it's extend
(lifetime) bound to that of the containing AD on the CLR. It's starts life when the class
loads and ends when to AD unloads.

That why I said that it's scope did not equal it's visibility, but you are right I should
have been more explicit and used "extend" instead of "scope".

Willy.

Jon Skeet [C# MVP]

unread,
Feb 28, 2007, 1:30:21 PM2/28/07
to
Paul Werkowitz <newsg...@primaprogramm.de> wrote:
> > IMO, if f() is not using any class state, then the method should probably be
> > a static anyway. In which case "count" would be a static member var.
>
> That's how you have to do it in C# (but not in other languages, e.g. C++).
> In C# you have to write
>
> void f()
> {
> if ( count > 0 )
> Debug.Writeline( "recursion level" + count.ToString() );
> count++;
>
> // -- the internals of f
>
> count--
> }
>
> static int count;
>
> which, IMHO, is clearly inferior.

On the contrary. It makes it clear that it's part of the state of the
type, without me having to read the *body* of a single method. The
state *will* end up as part of the state of a type or an instance (and
the fact that you used a static variable rather than an instance one
above is an interesting decision, btw) so why not make it obvious?
Then, if it clearly doesn't belong as part of the state of the
type/instance, that suggests the encapsulation is wrong and it should
be part of the state of a different type/instance.

> > Moreover, I normally find I end up wanting "count" in class scope anyway as
> > many times you end up wanting to enumerate it for debug, statistics, or
> > other flow control in other parts of the class. I have wrote and read lots
> > of classes, and I never really come up with much need for local static
> > scope.
>
> If it's not appropriate, then simply don't use static locals. I gave an
> example where it would be nice. Many other situations come to mind.

Well, I can't say I've missed them coming from C/C++. If I need state
for the sake of recursion, I tend to pass that in the recursive method
call. That's cleaner, IMO, and doesn't leave any state around for
longer than it makes sense, unlike static local variables.

> >I can think of one time similar to above, but the fix is easy and
> > probably not worth the change to the language. However, if I had to bet, I
> > would guess they add it at some point.
>
> It would be a non-breaking change, and could have been added with V3. The
> fact that nobody complains sheds some light on peoples mindsets. Of course
> you can circumvent it - like nearly everything. If you hadn't local
> variables at all, you could fix that in the same way, too.....

I would personally be against the change, for the reasons above.

Jon Skeet [C# MVP]

unread,
Feb 28, 2007, 1:34:51 PM2/28/07
to
Willy Denoyette [MVP] <willy.d...@telenet.be> wrote:
> > And, BTW, my question is still unanswered: How do you implement the given
> > task in C#?
> >>
> You can't in C#, VB.NET allows you to "declare" a local static, but this is simply
> syntactic sugar, the static still becomes a *type* variable (NOT an instance nor a local
> variable)

I don't think that's quite right. If the Sub/Proc is a Shared one, it
becomes a "static variable" (C# terminology) but if it's not, it
becomes an "instance variable" (C# terminology). At least, that's what
my experimentation shows. Compile this as a DLL:

Public Class Foo

Public Sub First()
Static inFirst As Integer = 0
End Sub

Public Shared Sub Second ()
Static inSecond As Integer = 0
End Sub

End Class

The generated $STATIC$First$2001$inFirst variable is an instance
variable, but $STATIC$Second$001$inSecond is a static variable.

Jon Skeet [C# MVP]

unread,
Feb 28, 2007, 1:42:16 PM2/28/07
to
Zytan <zytanl...@yahoo.com> wrote:
> > This function is legal. The C# compiler will precompute x and embed
> > it as a literal constant in the instruction stream.
>
> I noticed that I can't do this:
> const int x = MyMethod();
> because MyMethod() isn't constant.
>
> But, what I want to do is that after x is assigned, not allow it to
> change. C# doesn't allow that. I wonder why.

You can't do that for a local variable, but you can for a member
variable. I've never wanted to do it for a local variable - it's easy
enough to make sure that you never change it, because there shouldn't
be too much code to look through.

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 3:07:31 PM2/28/07
to
"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.204fdba9f...@msnews.microsoft.com...

> Willy Denoyette [MVP] <willy.d...@telenet.be> wrote:
>> > And, BTW, my question is still unanswered: How do you implement the given
>> > task in C#?
>> >>
>> You can't in C#, VB.NET allows you to "declare" a local static, but this is simply
>> syntactic sugar, the static still becomes a *type* variable (NOT an instance nor a local
>> variable)
>
> I don't think that's quite right. If the Sub/Proc is a Shared one, it
> becomes a "static variable" (C# terminology) but if it's not, it
> becomes an "instance variable" (C# terminology). At least, that's what
> my experimentation shows. Compile this as a DLL:
>
> Public Class Foo
>
> Public Sub First()
> Static inFirst As Integer = 0
> End Sub
>
> Public Shared Sub Second ()
> Static inSecond As Integer = 0
> End Sub
>
> End Class
>
> The generated $STATIC$First$2001$inFirst variable is an instance
> variable, but $STATIC$Second$001$inSecond is a static variable.
>


True, it would otherwise be impossible to access the shared (static) class-level variable, I
would have hoped the compiler to produce a warning as it's clearly not the intend of the
author of the method to declare a local as being shared (static )when it turns out it's not.
Note that even in this particular case, the compiler goes to a great lengths to protect the
variable during initialization, by generating some helper code which wraps the
initialization by a Monitor.Enter/Exit construct, really funny.

Willy.


Willy Denoyette [MVP]

unread,
Feb 28, 2007, 3:46:49 PM2/28/07
to
"Willy Denoyette [MVP]" <willy.d...@telenet.be> wrote in message
news:u4$n5P3WH...@TK2MSFTNGP03.phx.gbl...

C++/CLI also supports local statics and follows the initialization behavior as imposed by
the C++ Standard, that means it's not thread safe.

Following class:
public ref class C
{
public:
C(){}
static void Foo()
{
static int i = 1;
}
};

Produces a static with global scope, irrespective the method's declaration (static or
other).

Willy.


Zytan

unread,
Feb 28, 2007, 4:13:41 PM2/28/07
to
> True, visibility = lexical scope. What i really was trying to say was that the extend (or
> lifetime) was different.

I think you mean "extent" :) I don't know why we all don't just use
'visible' and 'lifetime', rather than 'scope' and 'extent'.

> Consider this small sample in vb.net:
>
> Public Class C
> Public Sub Foo(item As Integer)
> Static staticLocal As Integer = -1
> staticLocal = item
> End Sub
> End Class

Ok, so statics are allowed in VB, right.

> here "staticLocal " is declared as a static local, that means that "staticLocal " lexical
> scope is equal to it's active binding in program code, that is from the beginning of Foo
> till Foo returns, which is also it's visibility as far as Foo is concerned.
> Now, the variable itself is a static (and really a type variable), as such has it's extend
> (lifetime) bound to that of the containing AD on the CLR. It's starts life when the class
> loads and ends when to AD unloads.

Right, I understand the difference between scope and extent.

AD = ?

Zytan

Zytan

unread,
Feb 28, 2007, 4:17:16 PM2/28/07
to
> > I noticed that I can't do this:
> > const int x = MyMethod();
> > because MyMethod() isn't constant.
>
> > But, what I want to do is that after x is assigned, not allow it to
> > change. C# doesn't allow that. I wonder why.
>
> You can't do that for a local variable, but you can for a member
> variable. I've never wanted to do it for a local variable - it's easy
> enough to make sure that you never change it, because there shouldn't
> be too much code to look through.

Aaaah, and this is where you are doing the job that the compiler could
do. C# is robust and forces good programming, but this is one place
where VB and C# are lacking. I bet C# also disallows const parameters
like I frustrating found that VB doesn't have? I had a nice
discussion about this in the VB newsgroups.

So C# isn't so perfect after all. :)

I won't get into detail here, but the use of "const" offers many, many
wonderful features that people just don't know about until they use a
language that offers it, like C++. It's a godsend. You don't miss it
until you have it, and only then do you realize what it brings. I'll
find the link to the VB newsgroup thread if any wish to know about
them all.

Zytan

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 5:29:47 PM2/28/07
to
"Zytan" <zytanl...@yahoo.com> wrote in message
news:1172697221.0...@a75g2000cwd.googlegroups.com...

>> True, visibility = lexical scope. What i really was trying to say was that the extend (or
>> lifetime) was different.
>
> I think you mean "extent" :) I don't know why we all don't just use
> 'visible' and 'lifetime', rather than 'scope' and 'extent'.
>

Right, extent.
Scope and visibility are most often used and this since a very long time in computer lanage
parlance.
A variables scope is most often related to it's lifetime, that is , how long that variable
exists in computers memory, most often the scope is the same as it's visibility, but there
are exceptions. That's why I said that in the case of a "local static" variable, that it's
"visibility" is not the same as it's scope, the variable doesn't cease to exist when it
leaves it's enclosing lexical scope.
Anyway, this is a can of worms I'm not going to open any further ;-)

>> Consider this small sample in vb.net:
>>
>> Public Class C
>> Public Sub Foo(item As Integer)
>> Static staticLocal As Integer = -1
>> staticLocal = item
>> End Sub
>> End Class
>
> Ok, so statics are allowed in VB, right.
>
>> here "staticLocal " is declared as a static local, that means that "staticLocal " lexical
>> scope is equal to it's active binding in program code, that is from the beginning of Foo
>> till Foo returns, which is also it's visibility as far as Foo is concerned.
>> Now, the variable itself is a static (and really a type variable), as such has it's
>> extend
>> (lifetime) bound to that of the containing AD on the CLR. It's starts life when the class
>> loads and ends when to AD unloads.
>
> Right, I understand the difference between scope and extent.
>
> AD = ?

Application Domain.

Willy.

Willy Denoyette [MVP]

unread,
Feb 28, 2007, 5:44:55 PM2/28/07
to
"Zytan" <zytanl...@yahoo.com> wrote in message
news:1172697436....@j27g2000cwj.googlegroups.com...


Don't forget that .NET (the CLI) is a multi language platform, imposing const correctness in
one language makes no sense if it's not enforced by all languages available for the
platform, more, it makes little sense if not enforced by the CLR.
Even C++ (the single language) doesn't enforce, const-correctness, it even provides a
facility to cast-away const.
Even if C# and VB were the only languages on .NET, it was simply not possible to enforce
const correctness, it's just too late unless MSFT is willing to re-write all FCL and as such
probably break all existing applications.


Willy.

Zytan

unread,
Feb 28, 2007, 6:31:36 PM2/28/07
to
> Don't forget that .NET (the CLI) is a multi language platform, imposing const correctness in
> one language makes no sense if it's not enforced by all languages available for the
> platform, more, it makes little sense if not enforced by the CLR.

Yes, we got into that in the VB newsgroups. Perhaps that's why const
never made it in.

> Even C++ (the single language) doesn't enforce, const-correctness, it even provides a
> facility to cast-away const.

I discussed this, as well. No, you cannot cast away const. Not
directly. That's an important point.

Yes, it's possible to access and write over something that is const,
as you can with any language that lets you use pointers. So, it can
be 'cast-away' indirectly, but I don't think this should be called a
'cast', since it very much indirect.

The important distinction, as I went into detail in VB, is the
compiler checks that 'const' brings. The fact that it isn't a 100%
solution to prevention of variable changing is NOT why it is so
valuable.

It is valuable because, as most C# programmers should appreciate, for
the same reason that C# forces good programming ethics.

> Even if C# and VB were the only languages on .NET, it was simply not possible to enforce
> const correctness, it's just too late unless MSFT is willing to re-write all FCL and as such
> probably break all existing applications.

It is unforunate given what it can bring to writing robust code. It
is also unfortunate that people who haven't experienced it cannot
truly appreciate it. It would fit 100% into C#'s design, and effort
to force good code.

I fear I am starting the same conversation I had a few weeks ago.

Zytan

Bruce Wood

unread,
Feb 28, 2007, 11:49:01 PM2/28/07
to

This question came up at PDC'05, I believe, and if I recall the
response from the C# team was that const didn't make it into the
language because they were trying to figure out how to make it a 100%
solution, without providing the ability to cast it away, and without
ending up with the ugly cascading-cost problems that come up in C++
from time to time. Since they couldn't figure out how to do that, they
didn't include it in the language. Now it's probably too late. Too
bad, really.

Peter Duniho

unread,
Mar 1, 2007, 2:10:40 AM3/1/07
to
On Wed, 28 Feb 2007 08:18:55 +0800, Paul Werkowitz
<newsg...@primaprogramm.de> wrote:
>
> Now, how would you then write something like this in C#?
>
> void f()
> {
> static int count;
> if ( count > 0 )
> Debug.Writeline( "recursion level" + count.ToString() );
> count++;
>
> // -- the internals of f
>
> count--
> }

Well, I don't know how you would write it. But I would write it like this:

void f(int count)
{
if (count > 0)
{
Debug.WriteLine("recursion level " + count);
}

// -- the internals of f, which presumably include another
// call to f, such as:
f(count + 1);
}

If you have some objection to changing the callers of f(), then just
create a stub:

void f()
{
f(0);
}

and create a new function:

void f(int count)
{
f(count + 1);
// the rest of the function remains unchanged
}

In other words, just do the usual thing to overload the function that you
would in C#.

> IMHO, count is only interesting within the scope of f, and therefore
> should be defined in f, and nowhere else. But C# forces me to define such
> variables at class level, which is stupid.

See above. C# makes no such demand on you. It's true that it doesn't
allow for static local variables, but there are solutions other than
defining variables at the class level. Furthermore, I see very little
difference (if you are simply 100% against changing the function's
parameter list) between this:

void f()
{
static int count = 0;
}

and this:

static int count = 0;
void f()
{
}

It's true that the scope is different, but you're already breaking basic
laws of good coding practices by creating the static variable in the first
place. Just don't refer to the class-level member variable in other code,
if you feel that doing so would be a problem.

> (OK, its only a minor nuisance, and other things are much worse. But
> sometimes I wonder how language designers come to their results).

I too. I'm not really sure as to why the C# designers excluded static
local variables from the language. However, I do know that static locals
have very little practical use and are often abused (the biggest problem
is that when used, they can easily lead to code that is harder to
maintain, because the function behavior is not deterministic in a readily
apparent way...sort of a "kissing cousin" to code with side-effects, which
is another bad practice).

Another possibility is that static locals break the usual variable
initialization paradigm. That is, normally a variable declared within a
block is always initialized when that block of code is entered. Static
variables are initialized globally, only once. A common enough bug is a
variable declared locally as static, but which the programmer thinks is
initialized each time the block of code is entered. Getting rid of static
locals helps preserve the uniform behavior of variable declarations in C#
and helps avoid bugs where a programmer makes the wrong assumption about
when or how a variable is initialized.

Perhaps one or more of these reasons is related to why C# doesn't have
static locals, perhaps none are. I don't know. What I do know is that
the lack of static locals doesn't represent any sort of significant
impediment to writing good code, and I don't agree that it forces a
programmer to do anything that could be characterized as "stupid". If
anything, it tends to discourage programmers from doing something stupid.

Pete

Peter Duniho

unread,
Mar 1, 2007, 2:10:36 AM3/1/07
to
On Wed, 28 Feb 2007 11:50:59 +0800, debipra...@gmail.com
<debipra...@gmail.com> wrote:
>
> Some where I read (may be "FAQ in C++"), even in C++ this kind of
> local static variable is not safe for multi threaded applications. So,
> better use functionoid.

That's very true. Of course, it would be true of any data referenced by a
function that may be executed by multiple threads. I suppose one other
argument (in addition to the ones I mention in my other post) is that in
other cases, it should be more clear to the programmer that the use of the
data is not thread-safe, whereas a static local may not be readily
apparent to a programmer as not being thread-safe.

And of course, my proposed alternate solution (using a parameter to the
function rather than a static local) solves the thread safety problem, by
creating a new copy of the data for each iteration of the function (and
thus also for each thread).

Pete

Willy Denoyette [MVP]

unread,
Mar 1, 2007, 9:12:28 AM3/1/07
to
"Zytan" <zytanl...@yahoo.com> wrote in message
news:1172705496....@j27g2000cwj.googlegroups.com...

>> Don't forget that .NET (the CLI) is a multi language platform, imposing const correctness
>> in
>> one language makes no sense if it's not enforced by all languages available for the
>> platform, more, it makes little sense if not enforced by the CLR.
>
> Yes, we got into that in the VB newsgroups. Perhaps that's why const
> never made it in.
>
>> Even C++ (the single language) doesn't enforce, const-correctness, it even provides a
>> facility to cast-away const.
>
> I discussed this, as well. No, you cannot cast away const. Not
> directly. That's an important point.
>


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, it's possible to access and write over something that is const,
> as you can with any language that lets you use pointers. So, it can
> be 'cast-away' indirectly, but I don't think this should be called a
> 'cast', since it very much indirect.
>

Name it as you like, the const_cast operator is meant to cast-away const.

> The important distinction, as I went into detail in VB, is the
> compiler checks that 'const' brings. The fact that it isn't a 100%
> solution to prevention of variable changing is NOT why it is so
> valuable.
>

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.
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.
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.

Consider following sample.

// Compile with: cl /clr:safe filename.cpp
//
using namespace System;
public ref class B
{
public:
B() : i(0) {}
internal:
int i;
};


public ref class C
{
public:

int i;
void ChangeInt(const B^ b)
{
B^ myb = const_cast<B^>(b); // fool the compiler and cast away const
myb->i = 10 ; // modify i
Foo(myb); // do whatever you please with b
}
};
int main()
{
B^ b = gcnew B();
C c;
c.ChangeInt(b);
Console::WriteLine(b->i);
}

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.

> It is valuable because, as most C# programmers should appreciate, for
> the same reason that C# forces good programming ethics.
>

See above.

>> Even if C# and VB were the only languages on .NET, it was simply not possible to enforce
>> const correctness, it's just too late unless MSFT is willing to re-write all FCL and as
>> such
>> probably break all existing applications.
>
> It is unforunate given what it can bring to writing robust code. It
> is also unfortunate that people who haven't experienced it cannot
> truly appreciate it. It would fit 100% into C#'s design, and effort
> to force good code.
>

Yep, but as I said the CLI is a multilanguage platform, which is much more valuable than
non-enforced constness.

> I fear I am starting the same conversation I had a few weeks ago.
>

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.

Willy.


Paul Werkowitz

unread,
Mar 1, 2007, 10:07:22 AM3/1/07
to
Am Wed, 28 Feb 2007 18:03:08 +0100 schrieb Willy Denoyette [MVP]:

>>
>> Hello Willy,
>> I did not claim that count has "function scope". In fact, I did not say
>> anything about the scope of count at all.
>>
>
>> I said that count is interesting withing the scope of f only, which is a
>> different thing.
>>
>
> 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]



>> (Of course I know the answer - but it is worse) Maybe someone can enlighten
>> me why local statics are not in the language.
>
> 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

Laura T.

unread,
Mar 1, 2007, 10:11:49 AM3/1/07
to
Const is "Godsend"? IMO, on the contrary.
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.

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. If you declare a method
that takes a const Bla, you could pass it a non-const Bla. But if it's the
other way around you can't. If you declare a method that takes a non-const
Bla, you can't pass it a const Bla. So now you're stuck. So you gradually
need a const version of everything that isn't const, and you end up with a
shadow world. In C++ you get away with it, because as with anything in C++
it is purely optional whether you want this check or not. You can just whack
the constness away if you don't like it.
"

"Zytan" <zytanl...@yahoo.com> ha scritto nel messaggio
news:1172697436....@j27g2000cwj.googlegroups.com...

Paul Werkowitz

unread,
Mar 1, 2007, 10:57:53 AM3/1/07
to
Am Thu, 01 Mar 2007 15:10:40 +0800 schrieb Peter Duniho:

> Well, I don't know how you would write it. But I would write it like this:
>
> void f(int count)
> {
> if (count > 0)
> {
> Debug.WriteLine("recursion level " + count);
> }
>
> // -- the internals of f, which presumably include another
> // call to f, such as:
> f(count + 1);
> }
>

Well, I *definitely* do not want this. No No No!

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 - sometimes,
at least. But sometimes not. For debugging purposes I want to hit a
breakpoint if that ever happens. You are not advising me to give all these
functions an additional parameter? LOL.

[snip]

>> IMHO, count is only interesting within the scope of f, and therefore
>> should be defined in f, and nowhere else. But C# forces me to define such
>> variables at class level, which is stupid.
>
> See above. C# makes no such demand on you. It's true that it doesn't
> allow for static local variables, but there are solutions other than
> defining variables at the class level.

And these are?

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. What if h is used in another context,
where recursion is not an issue? what would the caller of h provide for the
value? You impose additional complexity on h and all clients of h simply
because f has some problem? No, sire.

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.

> Furthermore, I see very little
> difference (if you are simply 100% against changing the function's
> parameter list) between this:
>
> void f()
> {
> static int count = 0;
> }
>
> and this:
>
> static int count = 0;
> void f()
> {
> }
>
> It's true that the scope is different, but you're already breaking basic
> laws of good coding practices by creating the static variable in the first
> place.

Could you please elaborate a little why use of static variables is bad
coding practice? I can't see this.


>Just don't refer to the class-level member variable in other code,
> if you feel that doing so would be a problem.
>

Shudder. Then why do we need "private" at all? Simply don't refer to class
members that you feel should not be accessed from outside the class. You
can write some documentation for the user of your class that this or that
field is not to be used from client code. Yes! Back to the basics! Make the
language easier!

[snip]

> However, I do know that static locals
> have very little practical use

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. 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.


> and are often abused (the biggest problem
> is that when used, they can easily lead to code that is harder to
> maintain, because the function behavior is not deterministic in a readily
> apparent way...sort of a "kissing cousin" to code with side-effects, which
> is another bad practice).

Harder to maintain? Not really. Side effects? You should give an example,
how a static local variable would allow for any side effect.

>
> Another possibility is that static locals break the usual variable
> initialization paradigm. That is, normally a variable declared within a
> block is always initialized when that block of code is entered. Static
> variables are initialized globally, only once.

Yes. But same argumentation holds for statics at class level. Non-statics
are initialized in the ctor, statics are not. Same thing, different place.

> A common enough bug is a
> variable declared locally as static, but which the programmer thinks is
> initialized each time the block of code is entered.

Well, if the programmer does not know the rulez, I can't help. 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?

> Getting rid of static
> locals helps preserve the uniform behavior of variable declarations in C#
> and helps avoid bugs where a programmer makes the wrong assumption about
> when or how a variable is initialized.

Look at class level. There is no "uniform behavior" of variables. statics
are different bests that non statics. If this is too difficult - don't use
statics. Period.

[dnip]


> the lack of static locals doesn't represent any sort of significant
> impediment to writing good code, and I don't agree that it forces a
> programmer to do anything that could be characterized as "stupid".


Well, then give an implementation of the "recursion detection problem" in
C# that is acceptable.

Paule


Willy Denoyette [MVP]

unread,
Mar 1, 2007, 12:09:19 PM3/1/07
to
"Paul Werkowitz" <newsg...@primaprogramm.de> wrote in message
news:n2fzl6k80f8p$.1ho1xpf43k7dd.dlg@40tude.net...

Zytan

unread,
Mar 1, 2007, 12:31:27 PM3/1/07
to
> 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.

I completely agree. You can't argue against this.

> 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.

The recursion example is the only one I have used (other than for
quick debuggin test code), so maybe it's not useful enough for the C#
to warrant its inclusion?

Zytan

Zytan

unread,
Mar 1, 2007, 12:54:41 PM3/1/07
to
> > IMHO, count is only interesting within the scope of f, and therefore
> > should be defined in f, and nowhere else. But C# forces me to define such
> > variables at class level, which is stupid.
>
> See above. C# makes no such demand on you. It's true that it doesn't
> allow for static local variables, but there are solutions other than
> defining variables at the class level.

Yes, they may not be as fast, but they exist.

> Furthermore, I see very little
> difference (if you are simply 100% against changing the function's
> parameter list) between this:
>
> void f()
> {
> static int count = 0;
> }
>
> and this:
>
> static int count = 0;
> void f()
> {
> }

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.

> It's true that the scope is different, but you're already breaking basic
> laws of good coding practices by creating the static variable in the first
> place.

What good coding practice is being broken? I don't follow.

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.

> Just don't refer to the class-level member variable in other code,
> if you feel that doing so would be a problem.

That's similar to saying 'just don't access the global variable where
you shouldn't be, if you feel that would be a problem'. Or, similar
to: 'just don't change the value of the variable if you want it to be
constant'. These are just cop-outs. 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.

> > (OK, its only a minor nuisance, and other things are much worse. But
> > sometimes I wonder how language designers come to their results).
>
> I too. I'm not really sure as to why the C# designers excluded static
> local variables from the language.

I thought maybe it had to do with type/reference variables? But they
wouldn't be a problem, would they, if static local vars existed?

> However, I do know that static locals
> have very little practical use and are often abused (the biggest problem
> is that when used, they can easily lead to code that is harder to
> maintain, because the function behavior is not deterministic in a readily
> apparent way...sort of a "kissing cousin" to code with side-effects, which
> is another bad practice).

Ah, now this makes sense. I agree. Kind of like the token searching
string function in C, which depends on the last call for how it reacts
the second and third times. Its funky that way. And we have local
statics to blame.

And it is true they have little practical use (little, not none).

So, I can see why they got rid of it. The time was better spent
elsewhere. 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.

I never really ran into abuse of local statics, so I didn't consider
this. Thanks.

> Another possibility is that static locals break the usual variable
> initialization paradigm. That is, normally a variable declared within a
> block is always initialized when that block of code is entered. Static
> variables are initialized globally, only once. A common enough bug is a
> variable declared locally as static, but which the programmer thinks is
> initialized each time the block of code is entered. Getting rid of static
> locals helps preserve the uniform behavior of variable declarations in C#
> and helps avoid bugs where a programmer makes the wrong assumption about
> when or how a variable is initialized.

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!

> Perhaps one or more of these reasons is related to why C# doesn't have
> static locals, perhaps none are. I don't know. What I do know is that
> the lack of static locals doesn't represent any sort of significant
> impediment to writing good code, and I don't agree that it forces a
> programmer to do anything that could be characterized as "stupid". If
> anything, it tends to discourage programmers from doing something stupid.

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'). 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.

I still miss them, though.

Zytan

Zytan

unread,
Mar 1, 2007, 12:59:30 PM3/1/07
to
> Could you please elaborate a little why use of static variables is bad
> coding practice?

The answer to this question is the key to this discussion.

Zytan

Zytan

unread,
Mar 1, 2007, 1:01:41 PM3/1/07
to
> This question came up at PDC'05, I believe, and if I recall the
> response from the C# team was that const didn't make it into the
> language because they were trying to figure out how to make it a 100%
> solution, without providing the ability to cast it away, and without
> ending up with the ugly cascading-cost problems that come up in C++
> from time to time. Since they couldn't figure out how to do that, they
> didn't include it in the language. Now it's probably too late. Too
> bad, really.

I didn't think the lack of ability to absolutely prevent const casting
away is an issue. Just because 0.1% of the population can pick locks,
does it mean you shouldn't use locks?

Zytan

Zytan

unread,
Mar 1, 2007, 1:15:06 PM3/1/07
to
> 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.

> > The important distinction, as I went into detail in VB, is the
> > compiler checks that 'const' brings. The fact that it isn't a 100%
> > solution to prevention of variable changing is NOT why it is so
> > valuable.
>
> 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.

> > It is unforunate given what it can bring to writing robust code. It
> > is also unfortunate that people who haven't experienced it cannot
> > truly appreciate it. It would fit 100% into C#'s design, and effort
> > to force good code.
>
> 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

Zytan

unread,
Mar 1, 2007, 1:27:19 PM3/1/07
to
> 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

Willy Denoyette [MVP]

unread,
Mar 1, 2007, 1:54:38 PM3/1/07
to
"Paul Werkowitz" <newsg...@primaprogramm.de> wrote in message
news:n2fzl6k80f8p$.1ho1xpf43k7dd.dlg@40tude.net...


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.

Willy Denoyette [MVP]

unread,
Mar 1, 2007, 2:53:25 PM3/1/07
to
"Zytan" <zytanl...@yahoo.com> wrote in message
news:1172772906.1...@z35g2000cwz.googlegroups.com...

>> 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."
>

So what? This is not what const_cast is designed for anyway.

>> 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.
>

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.


>> > The important distinction, as I went into detail in VB, is the
>> > compiler checks that 'const' brings. The fact that it isn't a 100%
>> > solution to prevention of variable changing is NOT why it is so
>> > valuable.
>>
>> 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.
>

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.

>> 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.
>

Well C++ is still alive and kicking :-)).

>> 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.
>

True, but this is not C++, it's no longer the language who dictates the rules.

>> > It is unforunate given what it can bring to writing robust code. It
>> > is also unfortunate that people who haven't experienced it cannot
>> > truly appreciate it. It would fit 100% into C#'s design, and effort
>> > to force good code.
>>
>> 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.

Wholeheartedly agreeing.

Willy.

Jon Skeet [C# MVP]

unread,
Mar 1, 2007, 3:18:59 PM3/1/07
to
Zytan <zytanl...@yahoo.com> wrote:
> > Perhaps one or more of these reasons is related to why C# doesn't have
> > static locals, perhaps none are. I don't know. What I do know is that
> > the lack of static locals doesn't represent any sort of significant
> > impediment to writing good code, and I don't agree that it forces a
> > programmer to do anything that could be characterized as "stupid". If
> > anything, it tends to discourage programmers from doing something stupid.
>
> 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.

Zytan

unread,
Mar 1, 2007, 4:03:18 PM3/1/07
to
> > 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

Jon Skeet [C# MVP]

unread,
Mar 1, 2007, 4:09:48 PM3/1/07
to
Zytan <zytanl...@yahoo.com> wrote:
> > > 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.

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.



> > 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.

:)

Peter Duniho

unread,
Mar 2, 2007, 1:16:30 AM3/2/07
to
On Thu, 01 Mar 2007 23:57:53 +0800, Paul Werkowitz
<newsg...@primaprogramm.de> wrote:
> [...]

> 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.

>> See above. C# makes no such demand on you. It's true that it doesn't
>> allow for static local variables, but there are solutions other than
>> defining variables at the class level.
>
> 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).

>> Just don't refer to the class-level member variable in other code,
>> if you feel that doing so would be a problem.
>
> 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.

>> and are often abused (the biggest problem
>> is that when used, they can easily lead to code that is harder to
>> maintain, because the function behavior is not deterministic in a
>> readily apparent way...sort of a "kissing cousin" to code with
>> side-effects, which is another bad practice).
>
> 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).

>> Another possibility is that static locals break the usual variable
>> initialization paradigm. That is, normally a variable declared within a
>> block is always initialized when that block of code is entered. Static
>> variables are initialized globally, only once.
>
> 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.

>> A common enough bug is a
>> variable declared locally as static, but which the programmer thinks is
>> initialized each time the block of code is entered.
>
> 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

Peter Duniho

unread,
Mar 2, 2007, 1:35:15 AM3/2/07
to
On Fri, 02 Mar 2007 01:54:41 +0800, Zytan <zytanl...@yahoo.com> wrote:

>> Furthermore, I see very little
>> difference (if you are simply 100% against changing the function's
>> parameter list) between this:
>>
>> void f()
>> {
>> static int count = 0;
>> }
>>
>> and this:
>>
>> static int count = 0;
>> void f()
>> {
>> }
>
> 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.

>> It's true that the scope is different, but you're already breaking basic
>> laws of good coding practices by creating the static variable in the
>> first
>> place.
>
> 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

Zytan

unread,
Mar 2, 2007, 11:26:27 AM3/2/07
to
> > 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

Paul Werkowitz

unread,
Mar 2, 2007, 12:35:03 PM3/2/07
to
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



Paul Werkowitz

unread,
Mar 2, 2007, 1:49:23 PM3/2/07
to
Am Fri, 02 Mar 2007 14:16:30 +0800 schrieb Peter Duniho:

> On Thu, 01 Mar 2007 23:57:53 +0800, Paul Werkowitz
> <newsg...@primaprogramm.de> wrote:
>> [...]
>> 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.)


>
>>> See above. C# makes no such demand on you. It's true that it doesn't
>>> allow for static local variables, but there are solutions other than
>>> defining variables at the class level.
>>
>> 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.
>

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...


>
>> 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.
>

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.

>> 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.

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)


>
>> 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.

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

Zytan

unread,
Mar 2, 2007, 2:30:54 PM3/2/07
to
> 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

Jon Skeet [C# MVP]

unread,
Mar 2, 2007, 2:41:39 PM3/2/07
to
Paul Werkowitz <newsg...@primaprogramm.de> wrote:

<snip>

> 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.

Willy Denoyette [MVP]

unread,
Mar 2, 2007, 3:27:30 PM3/2/07
to
"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.20528e496...@msnews.microsoft.com...

> Paul Werkowitz <newsg...@primaprogramm.de> wrote:
>
> <snip>
>
>> 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.

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.

Peter Duniho

unread,
Mar 3, 2007, 4:41:40 AM3/3/07
to
On Sat, 03 Mar 2007 00:26:27 +0800, Zytan <zytanl...@yahoo.com> wrote:

> 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

0 new messages